--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/AST.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+
+public abstract class Statement
+{
+}
+
+public class DeclareVariable : Statement
+{
+ public string Identifier;
+ public Expression Expression;
+}
+
+public class DeclareFunction : Statement
+{
+ public string FunctionName;
+ public DeclareVariable Parameter1;
+ public DeclareVariable Parameter2;
+ public DeclareVariable Parameter3;
+ public String ReturnType;
+ public Statement Body;
+}
+
+public class CallFunction : Statement
+{
+ public string FunctionName;
+ public Expression Parameter1;
+ public Expression Parameter2;
+ public Expression Parameter3;
+ public Identifier ReturnVariable;
+}
+
+public class Write : Statement
+{
+ public Expression Expression;
+}
+
+public class Assignment : Statement
+{
+ public string Identifier;
+ public Expression Expression;
+}
+
+public class For : Statement
+{
+ public string Identifier;
+ public Expression From;
+ public Expression To;
+ public Statement Body;
+}
+
+public class IfThenElse : Statement
+{
+ public Expression If;
+ public Statement Then;
+ public Statement Else;
+}
+
+public class IfThen : Statement
+{
+ public Expression LeftExpression;
+ public RelationalOperands Operand;
+ public Expression RightExpression;
+ public Statement ThenBody;
+ public Statement ElseBody;
+}
+
+public class While : Statement
+{
+ public Expression LeftExpression;
+ public RelationalOperands Operand;
+ public Expression RightExpression;
+ public Statement Body;
+}
+
+public class ReadInput : Statement
+{
+ public string Identifier;
+}
+
+public class StatementSequence : Statement
+{
+ public Statement Left;
+ public Statement Right;
+}
+
+public abstract class Expression
+{
+}
+
+public class AlphaNumericValue : Expression
+{
+ public string Value;
+}
+
+public class NumericValue : Expression
+{
+ public int Value;
+}
+
+public class Identifier : Expression
+{
+ public string IdentifierName;
+}
+
+public class ArithmaticExpression : Expression
+{
+ public Expression Left;
+ public Expression Right;
+ public ArithmaticOperands Operand;
+}
+
+public enum ArithmaticOperands
+{
+ Add,
+ Subtract,
+ Multiply,
+ Division
+}
+
+public class LogicalExpression : Expression
+{
+ public Expression Left;
+ public Expression Right;
+ public LogicalOperands Operand;
+}
+
+public enum LogicalOperands
+{
+ Or,
+ And,
+ Xor,
+ Not
+}
+
+public class RelationalExpression : Expression
+{
+ public Expression Left;
+ public Expression Right;
+ public RelationalOperands Operand;
+}
+
+public class CompareVariable : Statement
+{
+ public string Identifier;
+ public Expression Expression;
+ public RelationalOperands Operand;
+}
+
+public enum RelationalOperands
+{
+ EqualTo,
+ NotEqualTo,
+ LessThan,
+ LessThanOrEqualTo,
+ GreaterThan,
+ GreaterThanOrEqualTo
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Factorial2.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,13 @@
+var fact = 7;
+
+fact = fact + 1;
+
+var c = 0;
+var result = 1;
+
+for c = 1 to fact do
+ result = result * c;
+end;
+
+print "The factorial is:";
+print result;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Fibonaci.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,19 @@
+var fib = 0;
+print "Enter a number to calculate fibonaci";
+read fib;
+fib = fib + 1;
+
+var a = 0;
+var b = 1;
+
+var i = 0;
+for i = 0 to fib do
+ var temp = a;
+ a = b;
+ b = temp + b;
+end;
+
+print "The result is:";
+print b;
+
+read b;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Fibonaci3.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,16 @@
+var fib = 7;
+
+fib = fib + 1;
+
+var a = 0;
+var b = 1;
+
+var i = 0;
+for i = 0 to fib do
+ var temp = a;
+ a = b;
+ b = temp + b;
+end;
+
+print "The result is:";
+print b;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Greetings.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,11 @@
+var x = 2;
+var y = 3;
+var z = y;
+print z;
+
+var msg = "Hello World";
+print msg;
+
+var n = 0;
+print "Enter any number from 0 to 9 to continue";
+read n;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Math.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,6 @@
+var a = 5;
+
+
+a = a + 3;
+print a;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Nested-For.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,15 @@
+var n = 0;
+print "Rate King's College from 1 to 10";
+read n;
+
+var x = 0;
+for x = 0 to n do
+ print "King's College is the best!";
+
+ var z = 0;
+ for z = x to n do
+ print z;
+ end;
+end;
+
+read n;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/Nested-For2.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,13 @@
+print "Rate King's College from 1 to 10";
+var n = 5;
+
+var x = 0;
+for x = 0 to n do
+ print "King's College is the best!";
+
+ var z = 0;
+ for z = x to n do
+ print z;
+ end;
+end;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/While.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,11 @@
+var FirstNum = 10;
+var SecondNum = 5;
+
+while FirstNum > SecondNum do
+ print FirstNum;
+
+ FirstNum = FirstNum - 1;
+endwhile;
+
+print "Enter any number to continue";
+read SecondNum;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/code.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,11 @@
+void TestFunction var output = 0, var inputA = 1, var inputB = 2
+begin
+ var test = 0;
+ test = inputA + inputB;
+ print test;
+endfunc;
+
+var one = 1;
+var two = 2;
+var three = 3;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/for-loop.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,11 @@
+var ntimes = 0;
+print "Rate King's College from 1 to 10";
+read ntimes;
+var x = 0;
+var y = 0;
+for x = y to ntimes do
+ print "King's College is the best";
+end;
+print "press any key to continue...";
+var continue = 0;
+read continue;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/if-then.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,23 @@
+var FirstNum = 0;
+var SecondNum = 0;
+
+print "enter first number";
+read FirstNum;
+
+print "enter second number";
+read SecondNum;
+
+if FirstNum > SecondNum then
+ if FirstNum > 9 then
+ print "First Number is greater then 9";
+ else
+ print "First Number is less then 9";
+ endif;
+ print "first number is GREATER than second number";
+else
+ print "first number is LESS than second number";
+endif;
+
+var z = 0;
+print "enter any number to continue";
+read z;
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Code/if-then2.kcl Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,16 @@
+var FirstNum = 25;
+var SecondNum = 15;
+
+
+
+if FirstNum > SecondNum then
+ if FirstNum > 9 then
+ print "First Number is greater then 9";
+ else
+ print "First Number is less then 9";
+ endif;
+ print "first number is GREATER than second number";
+else
+ print "first number is LESS than second number";
+endif;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/CodeGenerator.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,874 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+// Added
+using System.Reflection;
+using System.Reflection.Emit;
+using System.IO;
+
+public sealed class CodeGenerator
+{
+
+ Dictionary<string, System.Reflection.Emit.LocalBuilder> tblIdentifier;
+ Dictionary<string, System.Reflection.Emit.LocalBuilder> tblArguments;
+ TypeBuilder _typeBuilder = null;
+ System.Reflection.Emit.ILGenerator _ILGenerator = null;
+ MemberInfo WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
+
+ #region Statement
+ public CodeGenerator(Statement statement, string fileName)
+ {
+ string strFileName = Path.GetFileNameWithoutExtension(fileName);
+
+ #region Define Assembly
+ //AssemblyName _AssemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(fileName));
+ AssemblyName _AssemblyName = new AssemblyName(strFileName);
+ AppDomain currentDomain = AppDomain.CurrentDomain;
+ AssemblyBuilder _AssemblyBuilder = currentDomain.DefineDynamicAssembly(_AssemblyName, AssemblyBuilderAccess.Save);
+ #endregion
+
+ #region Define Module
+ ModuleBuilder _ModuleBuilder = _AssemblyBuilder.DefineDynamicModule(fileName);
+ #endregion
+
+ _typeBuilder = _ModuleBuilder.DefineType("CodeGenerator");
+ MethodBuilder _MethodBuilder = _typeBuilder.DefineMethod
+ ("Main",
+ MethodAttributes.Static,
+ typeof(void),
+ System.Type.EmptyTypes);
+
+ _ILGenerator = _MethodBuilder.GetILGenerator();
+ tblIdentifier = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
+ tblArguments = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
+
+ // CIL generation
+ GenerateStatement(statement);
+
+ _ILGenerator.Emit(OpCodes.Ret);
+ _typeBuilder.CreateType();
+ _ModuleBuilder.CreateGlobalFunctions();
+ _AssemblyBuilder.SetEntryPoint(_MethodBuilder);
+ _AssemblyBuilder.Save(fileName);
+ tblIdentifier = null;
+ _ILGenerator = null;
+ }
+
+ public void GenerateStatement(Statement _statement)
+ {
+ if (_statement is StatementSequence)
+ {
+ StatementSequence _StatementSequence = (StatementSequence)_statement;
+ GenerateStatement(_StatementSequence.Left);
+ GenerateStatement(_StatementSequence.Right);
+ }
+
+ else if (_statement is DeclareVariable)
+ {
+ // declare a variable in symbol table
+ DeclareVariable declare = (DeclareVariable)_statement;
+ tblIdentifier[declare.Identifier] =
+ _ILGenerator.DeclareLocal(GetExpressionType(declare.Expression));
+
+ // set the initial value
+ Assignment assign = new Assignment();
+ assign.Identifier = declare.Identifier;
+ assign.Expression = declare.Expression;
+ GenerateStatement(assign);
+ }
+
+ else if (_statement is Assignment)
+ {
+ Assignment assign = (Assignment)_statement;
+ GenerateExpression(assign.Expression,
+ GetExpressionType(assign.Expression));
+ if (GetExpressionType(assign.Expression) == typeof(ArithmaticExpression))
+ {
+ SaveIdentifier(assign.Identifier, typeof(Int32));
+ }
+ else
+ {
+ SaveIdentifier(assign.Identifier,
+ GetExpressionType(assign.Expression));
+ }
+
+ }
+
+ else if (_statement is DeclareFunction)
+ {
+ GenerateStatementMethod(_statement);
+ }
+
+ else if (_statement is Write)
+ {
+ // for print keyword, call .net method for printscreen
+ GenerateExpression(((Write)_statement).Expression,
+ typeof(string));
+ _ILGenerator.Emit(OpCodes.Call,
+ typeof(System.Console).GetMethod("WriteLine",
+ new System.Type[] { typeof(string) }));
+ }
+
+ else if (_statement is ReadInput)
+ {
+ // call the readline method and parse input method
+ _ILGenerator.Emit(OpCodes.Call,
+ typeof(System.Console).GetMethod("ReadLine",
+ BindingFlags.Public | BindingFlags.Static,
+ null, new System.Type[] { }, null));
+ _ILGenerator.Emit(OpCodes.Call,
+ typeof(int).GetMethod("Parse",
+ BindingFlags.Public | BindingFlags.Static,
+ null, new System.Type[] { typeof(string) }, null));
+ // store the input value in local builder
+ SaveIdentifier(((ReadInput)_statement).Identifier, typeof(int));
+ }
+ else if (_statement is IfThenElse)
+ {
+
+ //IfThenElse ifThenElse = (IfThenElse)stmt;
+ //RelationalExpression relExpr = (RelationalExpression)ifThenElse.If;
+ //// if, left side only
+ //il.Emit(OpCodes.Stloc, symbolTable[relExpr.Left.ToString()]);
+ //Label lblIf = il.DefineLabel();
+ //il.Emit(OpCodes.Br, lblIf);
+ //// then
+ //Label lblThen = il.DefineLabel();
+ //il.MarkLabel(lblThen);
+
+ }
+
+ else if (_statement is While)
+ {
+ While _while = (While)_statement;
+ Label lblTest = _ILGenerator.DefineLabel();
+ Label lblEnd = _ILGenerator.DefineLabel();
+
+ if (_while.Operand == RelationalOperands.GreaterThan)
+ {
+ _ILGenerator.MarkLabel(lblTest);
+ GenerateExpression(_while.LeftExpression, typeof(int));
+ GenerateExpression(_while.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Cgt);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatement(_while.Body);
+ _ILGenerator.Emit(OpCodes.Br, lblTest);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ else if (_while.Operand == RelationalOperands.EqualTo)
+ {
+ _ILGenerator.MarkLabel(lblTest);
+ GenerateExpression(_while.LeftExpression, typeof(int));
+ GenerateExpression(_while.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Ceq);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatement(_while.Body);
+ _ILGenerator.Emit(OpCodes.Br, lblTest);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ else if (_while.Operand == RelationalOperands.LessThan)
+ {
+ _ILGenerator.MarkLabel(lblTest);
+ GenerateExpression(_while.LeftExpression, typeof(int));
+ GenerateExpression(_while.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Clt);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatement(_while.Body);
+ _ILGenerator.Emit(OpCodes.Br, lblTest);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ }
+ else if (_statement is IfThen)
+ {
+ #region
+ //////Label body = il.DefineLabel();
+
+ //////il.Emit(OpCodes.Ldc_I4, 1000);
+
+
+
+ /*
+ // var x = 0;
+ // if x < 5 then
+ // print "less than 5";
+ // endif;
+
+ IfThen ifThen = (IfThen)stmt;
+ // jump to test
+
+
+ // **test** if x LessThan 5? (do the test)
+ il.MarkLabel(test);
+ GenExpr(ifThen.LeftExpression, typeof(int));
+
+ */
+
+ //Label greaterThan = il.DefineLabel();
+
+ //IfThen ifThen = (IfThen)stmt;
+ //GenExpr(ifThen.LeftExpression, typeof(int));
+ //GenExpr(ifThen.RightExpression, typeof(int));
+ //if (ifThen.Operand == RelationalOperands.GreaterThan)
+ //{
+ //
+ //}
+ #endregion
+
+ IfThen ifThen = (IfThen)_statement;
+ Label lblElse = _ILGenerator.DefineLabel();
+ Label lblEnd = _ILGenerator.DefineLabel();
+
+ #region GreaterThan
+ if (ifThen.Operand == RelationalOperands.GreaterThan)
+ {
+ GenerateExpression(ifThen.LeftExpression, typeof(int));
+ GenerateExpression(ifThen.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Cgt);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatement(ifThen.ThenBody);
+ _ILGenerator.Emit(OpCodes.Br, lblEnd);
+
+ _ILGenerator.MarkLabel(lblElse);
+ GenerateStatement(ifThen.ElseBody);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ #endregion
+ #region EqualTo
+ else if (ifThen.Operand == RelationalOperands.EqualTo)
+ {
+ GenerateExpression(ifThen.LeftExpression, typeof(int));
+ GenerateExpression(ifThen.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Ceq);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatement(ifThen.ThenBody);
+ _ILGenerator.Emit(OpCodes.Br, lblEnd);
+
+ _ILGenerator.MarkLabel(lblElse);
+ GenerateStatement(ifThen.ElseBody);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ #endregion
+ #region LessThan
+ else if (ifThen.Operand == RelationalOperands.LessThan)
+ {
+ GenerateExpression(ifThen.LeftExpression, typeof(int));
+ GenerateExpression(ifThen.RightExpression, typeof(int));
+ _ILGenerator.Emit(OpCodes.Clt);
+ _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatement(ifThen.ThenBody);
+ _ILGenerator.Emit(OpCodes.Br, lblEnd);
+
+ _ILGenerator.MarkLabel(lblElse);
+ GenerateStatement(ifThen.ElseBody);
+
+ _ILGenerator.MarkLabel(lblEnd);
+ }
+ #endregion
+
+ #region
+ /*
+ Label gtTrue = il.DefineLabel();
+ Label gtFalse = il.DefineLabel();
+
+
+ */
+ #endregion
+
+ }
+ else if (_statement is For)
+ {
+ // example:
+ // for x = 0 to 100 do
+ // print "hello";
+ // end;
+
+ // x = 0
+ For forLoop = (For)_statement;
+ Assignment assign = new Assignment();
+ assign.Identifier = forLoop.Identifier;
+ assign.Expression = forLoop.From;
+ GenerateStatement(assign);
+ // jump to the test
+ Label test = _ILGenerator.DefineLabel();
+ _ILGenerator.Emit(OpCodes.Br, test);
+
+ // body statement
+ Label body = _ILGenerator.DefineLabel();
+ _ILGenerator.MarkLabel(body);
+ GenerateStatement(forLoop.Body);
+
+ // increase x
+ _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
+ _ILGenerator.Emit(OpCodes.Ldc_I4, 1);
+ _ILGenerator.Emit(OpCodes.Add);
+ SaveIdentifier(forLoop.Identifier, typeof(int));
+
+ // check if x is equal to 100
+ _ILGenerator.MarkLabel(test);
+ _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
+ GenerateExpression(forLoop.To, typeof(int));
+ _ILGenerator.Emit(OpCodes.Blt, body);
+ }
+
+ else
+ {
+ ExceptionHandler("unable to generate " + _statement.GetType().Name);
+ }
+ }
+
+ public void ExceptionHandler(string strException)
+ {
+ throw new Exception(strException);
+ }
+
+ public void SaveIdentifier(string IdentifierName, System.Type IdentifierType)
+ {
+ if (tblIdentifier.ContainsKey(IdentifierName))
+ {
+ LocalBuilder locb = tblIdentifier[IdentifierName];
+
+ if (locb.LocalType == IdentifierType)
+ {
+ _ILGenerator.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
+ }
+ else
+ {
+ ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
+ }
+ }
+ else
+ {
+ ExceptionHandler("variable not declared '" + IdentifierName + "'");
+ }
+ }
+
+ public void GenerateExpression(Expression _expression, System.Type expressionType)
+ {
+ System.Type typeOfExpression;
+
+ if (_expression is AlphaNumericValue)
+ {
+ typeOfExpression = typeof(string);
+ _ILGenerator.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
+ }
+ else if (_expression is NumericValue)
+ {
+ typeOfExpression = typeof(int);
+ _ILGenerator.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
+ }
+
+ else if (_expression is ArithmaticExpression)
+ {
+ typeOfExpression = GetExpressionType(_expression);
+
+ ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
+ GenerateExpression(arithmaticExpression.Left, GetExpressionType(arithmaticExpression.Left));
+ GenerateExpression(arithmaticExpression.Right, GetExpressionType(arithmaticExpression.Right));
+ if (arithmaticExpression.Operand == ArithmaticOperands.Add)
+ {
+ _ILGenerator.Emit(OpCodes.Add);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract)
+ {
+ _ILGenerator.Emit(OpCodes.Sub);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply)
+ {
+ _ILGenerator.Emit(OpCodes.Mul);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Division)
+ {
+ _ILGenerator.Emit(OpCodes.Div);
+ }
+ }
+
+
+ else if (_expression is Identifier)
+ {
+ string identifier = ((Identifier)_expression).IdentifierName;
+ typeOfExpression = GetExpressionType(_expression);
+
+ if (!tblIdentifier.ContainsKey(identifier))
+ {
+ ExceptionHandler("undeclared variable '" + identifier + "'");
+ }
+
+ _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
+ }
+
+ else
+ {
+ ExceptionHandler("can't generate " + _expression.GetType().Name);
+ typeOfExpression = null;
+ }
+
+ if (typeOfExpression != expressionType)
+ {
+ if (typeOfExpression == typeof(int) &&
+ expressionType == typeof(string))
+ {
+ _ILGenerator.Emit(OpCodes.Box, typeof(int));
+ _ILGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
+ }
+ else
+ {
+ ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
+ }
+ }
+
+ }
+
+ public System.Type GetExpressionType(Expression _expression)
+ {
+ if (_expression is AlphaNumericValue)
+ {
+ return typeof(string);
+ }
+ else if (_expression is NumericValue)
+ {
+ return typeof(int);
+ }
+ else if (_expression is Identifier)
+ {
+ Identifier var = (Identifier)_expression;
+ if (tblIdentifier.ContainsKey(var.IdentifierName))
+ {
+ LocalBuilder locb = tblIdentifier[var.IdentifierName];
+ return locb.LocalType;
+ }
+ else
+ {
+ ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
+ return null;
+ }
+ }
+ else if (_expression is ArithmaticExpression)
+ {
+ return typeof(ArithmaticExpression);
+ }
+ else
+ {
+ ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
+ return null;
+ }
+ }
+
+ #endregion
+
+ #region Method
+
+ System.Reflection.Emit.ILGenerator _ILMethod = null;
+ public void GenerateStatementMethod(Statement _statement)
+ {
+ #region Statement
+ if (_statement is StatementSequence)
+ {
+ StatementSequence _StatementSequence = (StatementSequence)_statement;
+ GenerateStatementMethod(_StatementSequence.Left);
+ GenerateStatementMethod(_StatementSequence.Right);
+ }
+ #endregion
+
+ #region Declare Variable
+ else if (_statement is DeclareVariable)
+ {
+ // declare a variable in symbol table
+ DeclareVariable declare = (DeclareVariable)_statement;
+ tblIdentifier[declare.Identifier] =
+ _ILMethod.DeclareLocal(GetExpressionTypeMethod(declare.Expression));
+
+ // set the initial value
+ Assignment assign = new Assignment();
+ assign.Identifier = declare.Identifier;
+ assign.Expression = declare.Expression;
+ GenerateStatementMethod(assign);
+ }
+ #endregion
+
+ #region Assignment
+ else if (_statement is Assignment)
+ {
+ Assignment assign = (Assignment)_statement;
+ GenerateExpressionMethod(assign.Expression, GetExpressionTypeMethod(assign.Expression));
+ if (GetExpressionTypeMethod(assign.Expression) == typeof(ArithmaticExpression))
+ {
+ SaveIdentifierMethod(assign.Identifier, typeof(Int32));
+ }
+ else
+ {
+ SaveIdentifierMethod(assign.Identifier,
+ GetExpressionTypeMethod(assign.Expression));
+ }
+
+ }
+ #endregion
+
+ else if (_statement is DeclareFunction)
+ {
+ DeclareFunction _DeclareFunction = (DeclareFunction)_statement;
+
+ string strFunctionName = _DeclareFunction.FunctionName;
+
+ Type ParameterType1 = GetExpressionTypeMethod(_DeclareFunction.Parameter1.Expression);
+ Type ParameterType2 = GetExpressionTypeMethod(_DeclareFunction.Parameter2.Expression);
+ Type ParameterType3 = GetExpressionTypeMethod(_DeclareFunction.Parameter3.Expression);
+ Type[] InputParameters = { ParameterType1, ParameterType2, ParameterType3 };
+
+ Type ReturnType = typeof(void);
+ if(_DeclareFunction.ReturnType == "void")
+ ReturnType = typeof(void);
+ else if (_DeclareFunction.ReturnType == "string")
+ ReturnType = typeof(string);
+ else if (_DeclareFunction.ReturnType == "numeric")
+ ReturnType = typeof(int);
+
+
+
+ //FieldBuilder Parameter1 = _typeBuilder.DefineField(_DeclareFunction.Parameter1.Identifier, ParameterType1, FieldAttributes.Private);
+ //FieldBuilder Parameter2 = _typeBuilder.DefineField(_DeclareFunction.Parameter2.Identifier, ParameterType2, FieldAttributes.Private);
+ //FieldBuilder Parameter3 = _typeBuilder.DefineField(_DeclareFunction.Parameter3.Identifier, ParameterType3, FieldAttributes.Private);
+
+ MethodBuilder NewMethod =
+ _typeBuilder.DefineMethod
+ (strFunctionName,
+ MethodAttributes.Static,
+ ReturnType,
+ InputParameters);
+
+ //ParameterBuilder poolRefBuilder = NewMethod.DefineParameter(1, ParameterAttributes.In, _DeclareFunction.Parameter1.Identifier);
+
+ _ILMethod = NewMethod.GetILGenerator();
+
+
+ //tblArguments[_DeclareFunction.Parameter0.Identifier] = _ILMethod.
+
+ tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType1);
+ GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType1);
+ //_ILMethod.Emit(OpCodes.Starg, 0);
+
+ tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType2);
+ GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType2);
+ //_ILMethod.Emit(OpCodes.Starg, 1);
+
+ tblArguments[_DeclareFunction.Parameter2.Identifier] = _ILMethod.DeclareLocal(ParameterType3);
+ GenerateExpressionMethod(_DeclareFunction.Parameter2.Expression, ParameterType3);
+ //_ILMethod.Emit(OpCodes.Starg, 2);
+
+ //GenerateStatementMethod(_DeclareFunction.Body);
+ //_ILMethod.Emit(OpCodes.Ret);
+ }
+
+ #region write-read
+ else if (_statement is Write)
+ {
+ // for print keyword, call .net method for printscreen
+ GenerateExpressionMethod(((Write)_statement).Expression,
+ typeof(string));
+ _ILMethod.Emit(OpCodes.Call,
+ typeof(System.Console).GetMethod("WriteLine",
+ new System.Type[] { typeof(string) }));
+ }
+
+ else if (_statement is ReadInput)
+ {
+ // call the readline method and parse input method
+ _ILMethod.Emit(OpCodes.Call,
+ typeof(System.Console).GetMethod("ReadLine",
+ BindingFlags.Public | BindingFlags.Static,
+ null, new System.Type[] { }, null));
+ _ILMethod.Emit(OpCodes.Call,
+ typeof(int).GetMethod("Parse",
+ BindingFlags.Public | BindingFlags.Static,
+ null, new System.Type[] { typeof(string) }, null));
+ // store the input value in local builder
+ SaveIdentifierMethod(((ReadInput)_statement).Identifier, typeof(int));
+ }
+ #endregion
+
+ #region While
+ else if (_statement is While)
+ {
+ While _while = (While)_statement;
+ Label lblTest = _ILMethod.DefineLabel();
+ Label lblEnd = _ILMethod.DefineLabel();
+
+ if (_while.Operand == RelationalOperands.GreaterThan)
+ {
+ _ILMethod.MarkLabel(lblTest);
+ GenerateExpressionMethod(_while.LeftExpression, typeof(int));
+ GenerateExpressionMethod(_while.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Cgt);
+ _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatementMethod(_while.Body);
+ _ILMethod.Emit(OpCodes.Br, lblTest);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ else if (_while.Operand == RelationalOperands.EqualTo)
+ {
+ _ILMethod.MarkLabel(lblTest);
+ GenerateExpressionMethod(_while.LeftExpression, typeof(int));
+ GenerateExpressionMethod(_while.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Ceq);
+ _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatementMethod(_while.Body);
+ _ILMethod.Emit(OpCodes.Br, lblTest);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ else if (_while.Operand == RelationalOperands.LessThan)
+ {
+ _ILMethod.MarkLabel(lblTest);
+ GenerateExpressionMethod(_while.LeftExpression, typeof(int));
+ GenerateExpressionMethod(_while.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Clt);
+ _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
+ GenerateStatementMethod(_while.Body);
+ _ILMethod.Emit(OpCodes.Br, lblTest);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ }
+ #endregion
+
+ #region If-Then
+ else if (_statement is IfThen)
+ {
+ IfThen ifThen = (IfThen)_statement;
+ Label lblElse = _ILMethod.DefineLabel();
+ Label lblEnd = _ILMethod.DefineLabel();
+
+ #region GreaterThan
+ if (ifThen.Operand == RelationalOperands.GreaterThan)
+ {
+ GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
+ GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Cgt);
+ _ILMethod.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatementMethod(ifThen.ThenBody);
+ _ILMethod.Emit(OpCodes.Br, lblEnd);
+
+ _ILMethod.MarkLabel(lblElse);
+ GenerateStatementMethod(ifThen.ElseBody);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ #endregion
+ #region EqualTo
+ else if (ifThen.Operand == RelationalOperands.EqualTo)
+ {
+ GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
+ GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Ceq);
+ _ILMethod.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatementMethod(ifThen.ThenBody);
+ _ILMethod.Emit(OpCodes.Br, lblEnd);
+
+ _ILMethod.MarkLabel(lblElse);
+ GenerateStatementMethod(ifThen.ElseBody);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ #endregion
+ #region LessThan
+ else if (ifThen.Operand == RelationalOperands.LessThan)
+ {
+ GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
+ GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
+ _ILMethod.Emit(OpCodes.Clt);
+ _ILMethod.Emit(OpCodes.Brfalse, lblElse);
+ GenerateStatementMethod(ifThen.ThenBody);
+ _ILMethod.Emit(OpCodes.Br, lblEnd);
+
+ _ILMethod.MarkLabel(lblElse);
+ GenerateStatementMethod(ifThen.ElseBody);
+
+ _ILMethod.MarkLabel(lblEnd);
+ }
+ #endregion
+ }
+ #endregion
+
+ #region for
+ else if (_statement is For)
+ {
+ For forLoop = (For)_statement;
+ Assignment assign = new Assignment();
+ assign.Identifier = forLoop.Identifier;
+ assign.Expression = forLoop.From;
+ GenerateStatementMethod(assign);
+
+ Label test = _ILMethod.DefineLabel();
+ _ILMethod.Emit(OpCodes.Br, test);
+
+ Label body = _ILMethod.DefineLabel();
+ _ILMethod.MarkLabel(body);
+ GenerateStatementMethod(forLoop.Body);
+
+ _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
+ _ILMethod.Emit(OpCodes.Ldc_I4, 1);
+ _ILMethod.Emit(OpCodes.Add);
+ SaveIdentifierMethod(forLoop.Identifier, typeof(int));
+
+ _ILMethod.MarkLabel(test);
+ _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
+ GenerateExpressionMethod(forLoop.To, typeof(int));
+ _ILMethod.Emit(OpCodes.Blt, body);
+ }
+ #endregion
+
+ else
+ {
+ ExceptionHandler("unable to generate " + _statement.GetType().Name);
+ }
+ }
+
+ public void SaveIdentifierMethod(string IdentifierName, System.Type IdentifierType)
+ {
+ if (tblIdentifier.ContainsKey(IdentifierName))
+ {
+ LocalBuilder locb = tblIdentifier[IdentifierName];
+
+ if (locb.LocalType == IdentifierType)
+ {
+ _ILMethod.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
+ }
+ else
+ {
+ ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
+ }
+ }
+ else
+ {
+ ExceptionHandler("variable not declared '" + IdentifierName + "'");
+ }
+ }
+
+ public void DeclareArgument() { }
+
+ public void GenerateExpressionMethod(Expression _expression, System.Type expressionType)
+ {
+ System.Type typeOfExpression;
+
+ if (_expression is AlphaNumericValue)
+ {
+ typeOfExpression = typeof(string);
+ _ILMethod.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
+ }
+ else if (_expression is NumericValue)
+ {
+ typeOfExpression = typeof(int);
+ _ILMethod.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
+ }
+
+ else if (_expression is ArithmaticExpression)
+ {
+ typeOfExpression = GetExpressionTypeMethod(_expression);
+
+ ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
+ GenerateExpressionMethod(arithmaticExpression.Left, GetExpressionTypeMethod(arithmaticExpression.Left));
+ GenerateExpressionMethod(arithmaticExpression.Right, GetExpressionTypeMethod(arithmaticExpression.Right));
+ if (arithmaticExpression.Operand == ArithmaticOperands.Add)
+ {
+ _ILMethod.Emit(OpCodes.Add);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract)
+ {
+ _ILMethod.Emit(OpCodes.Sub);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply)
+ {
+ _ILMethod.Emit(OpCodes.Mul);
+ }
+ else if (arithmaticExpression.Operand == ArithmaticOperands.Division)
+ {
+ _ILMethod.Emit(OpCodes.Div);
+ }
+ }
+
+
+ else if (_expression is Identifier)
+ {
+ string identifier = ((Identifier)_expression).IdentifierName;
+ typeOfExpression = GetExpressionTypeMethod(_expression);
+
+ if (!tblIdentifier.ContainsKey(identifier) && !tblArguments.ContainsKey(identifier))
+ {
+ ExceptionHandler("undeclared variable '" + identifier + "'");
+ }
+
+ if (tblIdentifier.ContainsKey(identifier))
+ _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
+ else
+ _ILMethod.Emit(OpCodes.Ldloc, tblArguments[identifier]);
+ }
+
+ else
+ {
+ ExceptionHandler("can't generate " + _expression.GetType().Name);
+ typeOfExpression = null;
+ }
+
+ if (typeOfExpression != expressionType)
+ {
+ if (typeOfExpression == typeof(int) &&
+ expressionType == typeof(string))
+ {
+ _ILMethod.Emit(OpCodes.Box, typeof(int));
+ _ILMethod.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
+ }
+ else
+ {
+ ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
+ }
+ }
+
+ }
+
+ public System.Type GetExpressionTypeMethod(Expression _expression)
+ {
+ if (_expression is AlphaNumericValue)
+ {
+ return typeof(string);
+ }
+ else if (_expression is NumericValue)
+ {
+ return typeof(int);
+ }
+ else if (_expression is Identifier)
+ {
+ Identifier var = (Identifier)_expression;
+ if (tblIdentifier.ContainsKey(var.IdentifierName))
+ {
+ LocalBuilder locb = tblIdentifier[var.IdentifierName];
+ return locb.LocalType;
+ }
+ else if (tblArguments.ContainsKey(var.IdentifierName))
+ {
+ LocalBuilder locb = tblArguments[var.IdentifierName];
+ return locb.LocalType;
+ }
+ else
+ {
+ ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
+ return null;
+ }
+ }
+ else if (_expression is ArithmaticExpression)
+ {
+ return typeof(ArithmaticExpression);
+ }
+ else
+ {
+ ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
+ return null;
+ }
+ }
+ #endregion
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/MCG-CS.csproj Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{565A7BA0-5CAA-4D5D-820F-D763BF484CD5}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MCG_CS</RootNamespace>
+ <AssemblyName>MCG-CS</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AST.cs" />
+ <Compile Include="CodeGenerator.cs" />
+ <Compile Include="Parser.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Scanner.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\Factorial.kcl" />
+ <None Include="Code\Fibonaci.kcl" />
+ <None Include="Code\if-then.kcl" />
+ <None Include="Code\Nested-For.kcl" />
+ <None Include="Code\Factorial2.kcl" />
+ <None Include="Code\Fibonaci3.kcl" />
+ <None Include="Code\Greetings.kcl" />
+ <None Include="Code\if-then2.kcl" />
+ <None Include="Code\for-loop.kcl" />
+ <None Include="Code\Math.kcl" />
+ <None Include="Code\While.kcl" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\code.kcl" />
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup>
+ <None Include="Code\Nested-For2.kcl" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/MCG-CS.sln Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCG-CS", "MCG-CS.csproj", "{565A7BA0-5CAA-4D5D-820F-D763BF484CD5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {565A7BA0-5CAA-4D5D-820F-D763BF484CD5}.Debug|x86.ActiveCfg = Debug|x86
+ {565A7BA0-5CAA-4D5D-820F-D763BF484CD5}.Debug|x86.Build.0 = Debug|x86
+ {565A7BA0-5CAA-4D5D-820F-D763BF484CD5}.Release|x86.ActiveCfg = Release|x86
+ {565A7BA0-5CAA-4D5D-820F-D763BF484CD5}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Binary file Fahad/MCG-CS/MCG-CS.suo has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Parser.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,515 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+public sealed class Parser
+{
+ private int currentToken;
+ private readonly Statement parsingOutput;
+ private IList<object> listTokens;
+
+
+ public Parser(IList<object> tokens)
+ {
+ listTokens = tokens;
+ currentToken = 0;
+ parsingOutput = ParseStatement();
+
+ }
+
+ public Statement GetParsedStatement
+ {
+ get { return parsingOutput; }
+ }
+
+ public void ExceptionHandler(string strException)
+ {
+ throw new Exception(strException);
+ }
+
+ private Statement ParseStatement()
+ {
+ Statement parsedStatement;
+
+ if (currentToken == listTokens.Count)
+ {
+ ExceptionHandler("statement was expected before end of file");
+ }
+
+ if (listTokens[currentToken].Equals("print"))
+ {
+ currentToken++;
+ Write _Write = new Write();
+ _Write.Expression = ParseExpression();
+ parsedStatement = _Write;
+ }
+
+ else if (listTokens[currentToken].Equals("var"))
+ {
+ currentToken++;
+ DeclareVariable _DeclareVariable = new DeclareVariable();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _DeclareVariable.Identifier = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("variable name was expected after 'var'");
+ }
+
+ currentToken++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("= sign was expected after 'var identifier'");
+ }
+
+ currentToken++;
+
+ _DeclareVariable.Expression = ParseExpression();
+ parsedStatement = _DeclareVariable;
+ }
+
+ else if (listTokens[currentToken].Equals("call"))
+ {
+ currentToken++;
+ CallFunction _CallFunction = new CallFunction();
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _CallFunction.FunctionName = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("function name is expected after 'call'");
+ }
+ currentToken++;
+
+ _CallFunction.Parameter1 = ParseExpression();
+
+ //index++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString())
+ {
+ ExceptionHandler("',' sign was expected after first parameter");
+ }
+
+ currentToken++;
+
+ _CallFunction.Parameter2 = ParseExpression();
+
+ //index++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString())
+ {
+ ExceptionHandler("',' sign was expected after second parameter");
+ }
+
+ currentToken++;
+
+ _CallFunction.Parameter3 = ParseExpression();
+
+ //index++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString())
+ {
+ ExceptionHandler("';' sign was expected after third parameter");
+ }
+
+ parsedStatement = _CallFunction;
+ }
+
+ else if (listTokens[currentToken].Equals("string") || listTokens[currentToken].Equals("numeric") || listTokens[currentToken].Equals("void"))
+ {
+ DeclareFunction _DeclareFunction = new DeclareFunction();
+ _DeclareFunction.ReturnType = listTokens[currentToken].ToString();
+ currentToken++;
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _DeclareFunction.FunctionName = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("function name is expected after return type");
+ }
+
+ currentToken++;
+
+ if (listTokens[currentToken].Equals("var"))
+ {
+ currentToken++;
+ DeclareVariable _DeclareVariable = new DeclareVariable();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _DeclareVariable.Identifier = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("variable name was expected after 'var'");
+ }
+
+ currentToken++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("= sign was expected after 'var identifier'");
+ }
+
+ currentToken++;
+
+ _DeclareVariable.Expression = ParseExpression();
+ _DeclareFunction.Parameter1 = _DeclareVariable;
+ }
+
+ currentToken++;
+
+ if (listTokens[currentToken].Equals("var"))
+ {
+ currentToken++;
+ DeclareVariable _DeclareVariable = new DeclareVariable();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _DeclareVariable.Identifier = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("variable name was expected after 'var'");
+ }
+
+ currentToken++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("= sign was expected after 'var identifier'");
+ }
+
+ currentToken++;
+
+ _DeclareVariable.Expression = ParseExpression();
+
+ _DeclareFunction.Parameter2 = _DeclareVariable;
+ }
+
+ currentToken++;
+
+ if (listTokens[currentToken].Equals("var"))
+ {
+ currentToken++;
+ DeclareVariable _DeclareVariable = new DeclareVariable();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _DeclareVariable.Identifier = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("variable name was expected after 'var'");
+ }
+
+ currentToken++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("= sign was expected after 'var identifier'");
+ }
+
+ currentToken++;
+
+ _DeclareVariable.Expression = ParseExpression();
+
+ _DeclareFunction.Parameter3 = _DeclareVariable;
+ }
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("begin"))
+ {
+ ExceptionHandler("expected 'begin' after input parameters");
+ }
+
+ currentToken++;
+ _DeclareFunction.Body = ParseStatement();
+ parsedStatement = _DeclareFunction;
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endfunc"))
+ {
+ ExceptionHandler("unterminated function', 'endfunc' expected at the end");
+ }
+
+ currentToken++;
+ }
+
+ else if (listTokens[currentToken].Equals("read"))
+ {
+ currentToken++;
+ ReadInput _ReadInput = new ReadInput();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _ReadInput.Identifier = (string)listTokens[currentToken++];
+ parsedStatement = _ReadInput;
+ }
+ else
+ {
+ ExceptionHandler("variable name is expected after 'read'");
+ parsedStatement = null;
+ }
+ }
+
+
+ // IfThenElse ifThenElse = new IfThenElse();
+
+ // RelationalExpression relExpr = new RelationalExpression();
+ // relExpr.Left = ParseExpression();
+ // if (listTokens[index] == Scanner.EqualTo)
+ // relExpr.Operand = RelationalOperands.EqualTo;
+ // else if (listTokens[index] == Scanner.LessThan)
+ // relExpr.Operand = RelationalOperands.LessThan;
+ // else if (listTokens[index] == Scanner.GreaterThan)
+ // relExpr.Operand = RelationalOperands.GreaterThan;
+ // else
+ // {
+ // ExceptionHandler("expected relational operand");
+ // }
+
+ // index++;
+ // relExpr.Right = ParseExpression();
+ // ifThenElse.If = relExpr;
+ // index++;
+ // ifThenElse.Then = ParseStatement();
+
+ // parsedStatement = ifThenElse;
+
+ // //index++;
+
+
+
+ else if (listTokens[this.currentToken].Equals("while"))
+ {
+ currentToken++;
+ While _while = new While();
+
+ _while.LeftExpression = ParseExpression();
+
+ if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString())
+ _while.Operand = RelationalOperands.EqualTo;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString())
+ _while.Operand = RelationalOperands.LessThan;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString())
+ _while.Operand = RelationalOperands.GreaterThan;
+ currentToken++;
+
+ _while.RightExpression = ParseExpression();
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do"))
+ {
+ ExceptionHandler("expected 'do' after while");
+ }
+ currentToken++;
+ _while.Body = ParseStatement();
+ parsedStatement = _while;
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endwhile"))
+ {
+ ExceptionHandler("unterminated 'while', endwhile expected at the end");
+ }
+
+ currentToken++;
+ }
+
+ else if (listTokens[this.currentToken].Equals("if"))
+ {
+ currentToken++;
+ IfThen _IfThen = new IfThen();
+
+ _IfThen.LeftExpression = ParseExpression();
+
+ if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString())
+ _IfThen.Operand = RelationalOperands.EqualTo;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString())
+ _IfThen.Operand = RelationalOperands.LessThan;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString())
+ _IfThen.Operand = RelationalOperands.GreaterThan;
+ currentToken++;
+
+ _IfThen.RightExpression = ParseExpression();
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("then"))
+ {
+ ExceptionHandler("expected 'then' after if");
+ }
+ currentToken++;
+ _IfThen.ThenBody = ParseStatement();
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("else"))
+ {
+ ExceptionHandler("'else' is expected");
+ }
+ currentToken++;
+ _IfThen.ElseBody = ParseStatement();
+
+ parsedStatement = _IfThen;
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endif"))
+ {
+ ExceptionHandler("unterminated 'if', endif expected at the end");
+ }
+
+ currentToken++;
+ }
+
+ else if (listTokens[currentToken].Equals("for"))
+ {
+ currentToken++;
+ For _For = new For();
+
+ if (currentToken < listTokens.Count && listTokens[currentToken] is string)
+ {
+ _For.Identifier = (string)listTokens[currentToken];
+ }
+ else
+ {
+ ExceptionHandler("expected identifier after 'for'");
+ }
+
+ currentToken++;
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("for missing '='");
+ }
+
+ currentToken++;
+
+ _For.From = ParseExpression();
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("to"))
+ {
+ ExceptionHandler("expected 'to' after for");
+ }
+
+ currentToken++;
+
+ _For.To = ParseExpression();
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do"))
+ {
+ ExceptionHandler("expected 'do' after from expression in for loop");
+ }
+
+ currentToken++;
+
+ _For.Body = ParseStatement();
+ parsedStatement = _For;
+
+ if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("end"))
+ {
+ ExceptionHandler("unterminated 'for' loop body");
+ }
+
+ currentToken++;
+ }
+
+ else if (listTokens[currentToken] is string)
+ {
+ // assignment
+
+ Assignment _Assignment = new Assignment();
+ _Assignment.Identifier = (string)listTokens[currentToken++];
+
+ if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString())
+ {
+ ExceptionHandler("expected '='");
+ }
+
+ currentToken++;
+
+ _Assignment.Expression = ParseExpression();
+ parsedStatement = _Assignment;
+ }
+ else
+ {
+ ExceptionHandler("parse error at token " + currentToken + ": " + listTokens[currentToken]);
+ parsedStatement = null;
+ }
+
+ if (currentToken < listTokens.Count && listTokens[currentToken].ToString() == Lexer.Tokens.Terminator.ToString())
+ {
+ currentToken++;
+
+ if (currentToken < listTokens.Count && !listTokens[currentToken].Equals("end")
+ && !listTokens[currentToken].Equals("else") && !listTokens[currentToken].Equals("endif")
+ && !listTokens[currentToken].Equals("endwhile") && !listTokens[currentToken].Equals("endfunc"))
+ {
+ StatementSequence sequence = new StatementSequence();
+ sequence.Left = parsedStatement;
+ sequence.Right = ParseStatement();
+ parsedStatement = sequence;
+ }
+ }
+
+ return parsedStatement;
+ }
+
+ private Expression ParseExpression()
+ {
+ Expression parsedExpression;
+
+ if (currentToken == listTokens.Count)
+ {
+ ExceptionHandler("expected expression, got EOF");
+ }
+
+ if (listTokens[currentToken] is StringBuilder)
+ {
+ string value = ((StringBuilder)listTokens[currentToken++]).ToString();
+ AlphaNumericValue _AlphaNumericValue = new AlphaNumericValue();
+ _AlphaNumericValue.Value = value;
+ parsedExpression = _AlphaNumericValue;
+ }
+ else if (listTokens[currentToken] is int)
+ {
+ int intValue = (int)listTokens[currentToken++];
+ NumericValue _NumericValue = new NumericValue();
+ _NumericValue.Value = intValue;
+ parsedExpression = _NumericValue;
+ }
+ else if (listTokens[currentToken] is string)
+ {
+ string identifier = (string)listTokens[currentToken++];
+ Identifier _Identifier = new Identifier();
+ _Identifier.IdentifierName = identifier;
+ parsedExpression = _Identifier;
+ }
+ else
+ {
+ ExceptionHandler("expected string literal, int literal, or variable");
+ return null;
+ }
+
+ //if (index < listTokens.Count && listTokens[index] != Scanner.Terminator && listTokens[index].GetType() != typeof(StringBuilder))
+ if (listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString())
+ {
+ if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString()
+ || listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString() || listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString())
+ {
+ ArithmaticExpression arithmaticExpression = new ArithmaticExpression();
+ arithmaticExpression.Left = parsedExpression;
+ if (listTokens[currentToken].ToString() == Lexer.Tokens.Add.ToString())
+ arithmaticExpression.Operand = ArithmaticOperands.Add;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.Subtract.ToString())
+ arithmaticExpression.Operand = ArithmaticOperands.Subtract;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.Multiply.ToString())
+ arithmaticExpression.Operand = ArithmaticOperands.Multiply;
+ else if (listTokens[currentToken].ToString() == Lexer.Tokens.Divide.ToString())
+ arithmaticExpression.Operand = ArithmaticOperands.Division;
+ currentToken++;
+
+ arithmaticExpression.Right = ParseExpression();
+ parsedExpression = arithmaticExpression;
+ }
+ }
+ return parsedExpression;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Program.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+// Added
+using System.IO;
+using System.Diagnostics;
+
+namespace MCG_CS
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ bool bExit = false;
+
+ while (bExit == false)
+ {
+ Console.WriteLine("\nPlease enter the file path or type quit to exit the application");
+ string strFileName = Console.ReadLine();
+
+ if (strFileName == "quit")
+ bExit = true;
+ else
+ {
+
+ try
+ {
+
+ Stopwatch timerParser = new Stopwatch();
+ Stopwatch timerCompiler = new Stopwatch();
+
+
+
+ //string strInputCodeFile = "Factorial.kcl";
+
+ //string strFileName = "C:\\Users\\fahad\\Desktop\\MCG-CS\\Code\\" + strInputCodeFile;
+
+ timerParser.Start();
+ TextReader inputFile = File.OpenText(strFileName);
+ Lexer _Lexer = new Lexer(inputFile);
+
+ IList<object> lexemes = _Lexer.GetLexemes;
+ Parser parser = new Parser(lexemes);
+
+ Console.WriteLine("\nParsing Time: " + (timerParser.ElapsedTicks).ToString());
+
+ timerCompiler.Start();
+
+ strFileName = Path.GetFileNameWithoutExtension(strFileName);
+ CodeGenerator codeGenerator = new CodeGenerator(parser.GetParsedStatement, strFileName + ".exe");
+
+ timerParser.Stop();
+ timerCompiler.Stop();
+
+
+ Console.WriteLine("Compiling Time: " + (timerCompiler.ElapsedTicks).ToString());
+ Console.WriteLine("Overall Time: " + (timerParser.ElapsedTicks).ToString());
+
+ Console.WriteLine("\nCode has been compiled successfully!");
+ Console.WriteLine("\nAn executable assembly file has been generated with the same name as input file and saved in BIN\\DEBUG folder");
+
+
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ Console.WriteLine("\nPress any key to continue...");
+ }
+
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Properties/AssemblyInfo.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MCG-CS")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MCG-CS")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5df7bd7a-49cf-4d1e-8b45-753f17828207")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/Scanner.cs Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,204 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+//Added
+using System.IO;
+
+public sealed class Lexer
+{
+ private readonly IList<object> listLexemes;
+
+ public Lexer(TextReader inputFile)
+ {
+ listLexemes = new List<object>();
+ ReadProgramFile(inputFile);
+ }
+
+ public IList<object> GetLexemes
+ {
+ get
+ {
+ return listLexemes;
+ }
+ }
+
+ public enum Tokens
+ {
+ Add,
+ Subtract,
+ Multiply,
+ Divide,
+ Terminator,
+ EqualTo,
+ LessThan,
+ GreaterThan,
+ Comma,
+ OpenParen,
+ CloseParen,
+ OpenBrac,
+ CloseBrac
+ }
+
+ private void ReadProgramFile(System.IO.TextReader programFile)
+ {
+ while (programFile.Peek() != -1)
+ {
+ char symbol = (char)programFile.Peek();
+
+ if (char.IsWhiteSpace(symbol))
+ {
+ // if the symbol is whitespace then move to next symbol
+ programFile.Read();
+ }
+ else if (char.IsLetter(symbol) || symbol == '_')
+ {
+ //identify the tokens
+
+ StringBuilder token = new StringBuilder();
+
+ while (char.IsLetter(symbol) || symbol == '_')
+ {
+ token.Append(symbol);
+ programFile.Read();
+
+ if (programFile.Peek() == -1)
+ {
+ break;
+ }
+ else
+ {
+ symbol = (char)programFile.Peek();
+ }
+ }
+
+ listLexemes.Add(token.ToString());
+ }
+ else if (symbol == '"')
+ {
+ // string literal
+ StringBuilder stringLiteral = new StringBuilder();
+
+ programFile.Read(); // skip the '"'
+
+ if (programFile.Peek() == -1)
+ {
+ throw new Exception("String literal is not terminated");
+ }
+
+ while ((symbol = (char)programFile.Peek()) != '"')
+ {
+ stringLiteral.Append(symbol);
+ programFile.Read();
+
+ if (programFile.Peek() == -1)
+ {
+ throw new Exception("String literal is not terminated");
+ }
+ }
+
+ // skip the terminating "
+ programFile.Read();
+ listLexemes.Add(stringLiteral);
+ }
+ else if (char.IsDigit(symbol))
+ {
+ // numeric literal
+
+ StringBuilder numericLiteral = new StringBuilder();
+
+ while (char.IsDigit(symbol))
+ {
+ numericLiteral.Append(symbol);
+ programFile.Read();
+
+ if (programFile.Peek() == -1)
+ {
+ break;
+ }
+ else
+ {
+ symbol = (char)programFile.Peek();
+ }
+ }
+
+ listLexemes.Add(int.Parse(numericLiteral.ToString()));
+ }
+ else switch (symbol)
+ {
+ case '(':
+ programFile.Read();
+ listLexemes.Add(Tokens.OpenParen);
+ break;
+
+ case ')':
+ programFile.Read();
+ listLexemes.Add(Tokens.CloseParen);
+ break;
+
+ case '=':
+ programFile.Read();
+ listLexemes.Add(Tokens.EqualTo);
+ break;
+
+ case ';':
+ programFile.Read();
+ listLexemes.Add(Tokens.Terminator);
+ break;
+
+ case '<':
+ programFile.Read();
+ listLexemes.Add(Tokens.LessThan);
+ break;
+
+ case '>':
+ programFile.Read();
+ listLexemes.Add(Tokens.GreaterThan);
+ break;
+
+ case ',':
+ programFile.Read();
+ listLexemes.Add(Tokens.Comma);
+ break;
+
+ case '/':
+ programFile.Read();
+ listLexemes.Add(Tokens.Divide);
+ break;
+
+ case '*':
+ programFile.Read();
+ listLexemes.Add(Tokens.Multiply);
+ break;
+
+ case '-':
+ programFile.Read();
+ listLexemes.Add(Tokens.Subtract);
+ break;
+
+ case '+':
+ programFile.Read();
+ listLexemes.Add(Tokens.Add);
+ break;
+
+ case '{':
+ programFile.Read();
+ listLexemes.Add(Tokens.OpenBrac);
+ break;
+
+ case '}':
+ programFile.Read();
+ listLexemes.Add(Tokens.CloseBrac);
+ break;
+
+ default:
+ ExceptionHandler("unidentified symbol '" + symbol + "'");
+ break;
+ }
+ }
+ }
+
+ public void ExceptionHandler(string strException)
+ {
+ throw new Exception(strException);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/readme.txt Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,13 @@
+Visual Studio 2010 is required to open this project.
+
+The project executable is saved in BIB\DEBUG folder with the name of MCG-CS.exe
+
+To generate an assembly file, run the project executable and provide the input code file path. Input file should be saved with an extension of *.kcl
+
+The generated assembly is saved inside "Bin\Debug\" folder. Assemblies are saved as an executable files and can be executed directly
+
+ILDASM.exe comand line tool is required to inspect the assembly. This tool is available in "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\" folder
+
+Sample code for some standard programing problems is given in CODE folder
+
+PROPERTIES, OBJ and BIN folders are auto-generated folders created by .NET runtime and shall not be modified