Beispiel #1
0
        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.
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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) }));
            }
        }
Beispiel #4
0
 public override void Push(Emit.ILGenerator ilg, ExecutionContext ec)
 {
     ilg.Emit(Emit.OpCodes.Ldstr, s);
 }
Beispiel #5
0
        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.");
        }
Beispiel #6
0
        //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");
            }
        }
Beispiel #7
0
        public override void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec)
        {
            if (this.returnExp != null)
                this.returnExp.Push(ilg, ec);

            ilg.Emit(Emit.OpCodes.Ret);
        }