so I am making my own compiler in C# for a custom Language called algebra.
I am following this tutorial http://msdn.microsoft.com/en-us/magazine/cc136756.aspx
Here is the source code of the compiler.
I think there is something wrong with the compiler code.
The code is quite big so I attach it as download links, if you don't want to download them you can look at the tutorial code as the code I have is basically the same.
https://www.dropbox.com/s/6h5fu7f6in3mtfw/Ast.cs
https://www.dropbox.com/s/lt6x8zjltq68q50/Parser.cs
https://www.dropbox.com/s/h84crc42472773s/Program.cs
https://www.dropbox.com/s/gkw2im5n1it28pb/Scanner.cs
https://www.dropbox.com/s/0gnx65to6pfna0y/CodeGen.cs
Here is the code that creates the message(Parser.cs):
public Parser(Collections.IList<object> tokens)
{
this.tokens = tokens;
this.index = 0;
this.result = this.ParseStmt();
if (this.index != this.tokens.Count)
throw new System.Exception("expected EOF");
}
This code scans for any operator signs(taking '+' as an example)(scanner.cs)
there is more code to this by the way.
case '+':
input.Read();
this.result.Add(Scanner.Add);
break;
This bit is just an enumeration(Ast.cs)
public enum BinOp
{
Add,
Sub,
Mul,
Div
}
CodeGen.cs
private void GenExpr(Expr expr, System.Type expectedType)
{
System.Type deliveredType;
if (expr is StringLiteral)
{
deliveredType = typeof(string);
this.il.Emit(Emit.OpCodes.Ldstr, ((StringLiteral)expr).Value);
}
else if (expr is IntLiteral)
{
deliveredType = typeof(int);
this.il.Emit(Emit.OpCodes.Ldc_I4, ((IntLiteral)expr).Value);
}
else if (expr is Variable)
{
string ident = ((Variable)expr).Ident;
deliveredType = this.TypeOfExpr(expr);
if (!this.symbolTable.ContainsKey(ident))
{
throw new System.Exception("undeclared variable '" + ident + "'");
}
this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[ident]);
}
else if (stmt is Print)
{
These are the 'write' and 'read' statements
this.GenExpr(((Print)stmt).Expr, typeof(string));
this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) }));
}
else if (stmt is ReadInt)
{
this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null));
this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null));
this.Store(((ReadInt)stmt).Ident, typeof(int));
}
more code here that defines variables ,expressions etc.
public abstract class Expr
{
}
public class StringLiteral : Expr
{
public string Value;
}
public class IntLiteral : Expr
{
public int Value;
}
public class Variable : Expr
{
public string Ident;
}
public class BinExpr : Expr
{
public Expr Left;
public Expr Right;
public BinOp Op;
}
More on the operators (scanner.cs)
#region ArithmiticConstants
public static readonly object Add = new object();
public static readonly object Sub = new object();
public static readonly object Mul = new object();
public static readonly object Div = new object();
public static readonly object Semi = new object();
public static readonly object Equal = new object();
#endregion
the problem looks like it's not possible to perform any mathematical operations on either a number or variable.
so for example I write such code and try to compile it however I get an error(expected EOF):
variable x = 9;
variable y = 10;
variable ans = x * y;
write ans;
here the output should be 90 however the compiler gives an error 'EOF expected'
However this works:
variable x = 9;
write x;
so I can confirm the language works
I would be very grateful if anyone could help me.
So I appreciate any help that I get. Thanks :)