public override void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec) { /* * Check for two things: * 1) Is it an argument? * 2) Is it a local variable (or global) */ var arg = ec.GetParameter(varName); if (arg != null) { //This is an argument - we need to store it in its index. ilg.Emit(Emit.OpCodes.Starg, arg.Position); return; } var varDec = ec.GetVariable(varName); if (varDec == null) { //The person wants this to be a local variable. It has not been declared, so we must do it for them. varDec = ilg.DeclareLocal(e.GetEvaluatedType(ec)); ec.AddVariable(varName, varDec); } e.Push(ilg, ec); ilg.Emit(Emit.OpCodes.Stloc, varDec); //Store the result of the expression. }
public override void Push(Emit.ILGenerator ilg, ExecutionContext ec) { var f = Function.Get(funcName).MethodInfo; var fec = Function.Get(funcName).Ec; int count = 0; var pars = fec.GetParameters(); foreach (Expression e in alist) { if (count >= fec.NumParameters) throw new Exception("Too many arguments to function."); if (pars[count++].Type == e.GetEvaluatedType(ec)) { e.Push(ilg, ec); } else { throw new Exception("Mismatch of argument types - no coercing available currently."); } } if (count < fec.NumParameters) throw new Exception("Too few arguments to function."); ilg.Emit(Emit.OpCodes.Call, Function.Get(funcName).MethodInfo); }
public override void Evaluate(Expression left, Expression right, Emit.ILGenerator ilg, ExecutionContext ec) { Type t = left.GetEvaluatedType(ec); Type t2 = right.GetEvaluatedType(ec); if (t != t2) { throw new NotImplementedException("Type coercion not implemented yet."); } if (t == typeof(string)) { //Concatenate strings! Fun for all. //TODO: optimize the shit out of this to determine if there is tons of concatenating going on because this is inefficient as hell for something like "lol" + "hi" + 3 //TODO: classes with operator overloading so I don't need to do special exceptions within the language code itself. I dislike that. left.Push(ilg, ec); right.Push(ilg, ec); ilg.Emit(Emit.OpCodes.Call, typeof(String).GetMethod("Concat", new Type[] { typeof(string), typeof(string) })); } }
public override void Push(Emit.ILGenerator ilg, ExecutionContext ec) { ilg.Emit(Emit.OpCodes.Ldstr, s); }
public override void Push(Emit.ILGenerator ilg, ExecutionContext ec) { /* * Check for three things: * 1) Is it an argument? * 2) Is it a local variable (or global) * 3) Is it a function call without parantheses? */ var arg = ec.GetParameter(name); if (arg != null) { //This is an argument - push its index onto the stack! ilg.Emit(Emit.OpCodes.Ldarg, arg.Position); return; } var varDec = ec.GetVariable(name); if (varDec != null) { //This is a local variable! Push it onto the stack. ilg.Emit(Emit.OpCodes.Ldloc, varDec); return; } var funcDec = Function.Get(name); if (funcDec != null) { if (funcDec.MethodInfo.ReturnType != typeof(void)) { ilg.Emit(Emit.OpCodes.Call, funcDec.MethodInfo); //Only functions without parameters can be called currently - changes to the grammar are needed to improve on this and will likely become their own type of expression return; } else { throw new Exception("Attempting to use a void type as an expression."); } } //At this point, we have an unrecognized identifier throw new Exception("Use of undeclared identifier in expression."); }
//Almacena el valor del tope de la pila en el nombre de variable proporcionado (no maneja ambito) public static void Almacenar(string nombre, Emit.ILGenerator _il) { if (!TablaDireccionesSimbolos.ContainsKey(nombre)) { TablaDireccionesSimbolos[nombre] = _il.DeclareLocal(typeof(System.Int32)); //Solo variables enteras } Emit.LocalBuilder variableLocal = TablaDireccionesSimbolos[nombre]; if (!variableLocal.LocalType.HasElementType) //(es una variable simple) verdadero solo en caso de vectores o matrices { _il.Emit(Emit.OpCodes.Stloc, TablaDireccionesSimbolos[nombre]); } else //es una matriz o vector y actuo acorde { throw new System.Exception("No se soportan arrays o matrices en las asignaciones"); } }
public override void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec) { if (this.returnExp != null) this.returnExp.Push(ilg, ec); ilg.Emit(Emit.OpCodes.Ret); }