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
 //For use with already-defined functions, like Console.WriteLine. Allows you to alias them for use inside the language.
 public Function(String funcName, MethodInfo mi)
 {
     fns.Add(funcName, this);
     this.mi = mi;
     ec = new ExecutionContext(null);
     var parInfos = mi.GetParameters();
     Parameter[] pars = new Parameter[parInfos.Length];
     for (int i = 0; i < pars.Length; i++)
         pars[i] = new Parameter(parInfos[i].ParameterType, parInfos[i].Name);
     ec.SetParameters(pars);
 }
Beispiel #4
0
 public Function(Identifier returnType, Identifier name, Sequence<Parameter> pars, Sequence<Statement> stmts)
 {
     Type[] tar = Parameter.ConvertSequenceToTypeArray(pars);
     var mb = CodeGenerator.CreateFunction(name.Value, TypeChecker.ConvertStringToType(returnType.Value), tar);
     mi = mb;
     this.stmts = stmts;
     if (fns.ContainsKey(name.Value))
     {
         throw new Exception("Function redeclared. Note: overloaded functions are not supported at this time.");
     }
     fns.Add(name.Value, this);
     int count = 1; //parameters start at index 1 - 0 is the return. not sure on GetParameters() though - more testing is needed, but i don't think it includes the returntype as there is a separate way to get that
     foreach (Parameter p in pars)
     {
         mb.DefineParameter(count++, ParameterAttributes.None, p.Name);
     }
     ec = new ExecutionContext(null);
     ec.SetParameters(pars.ToArray());
 }
Beispiel #5
0
 public override Type GetEvaluatedType(ExecutionContext ec)
 {
     return typeof(string);
 }
Beispiel #6
0
 public abstract void Push(Emit.ILGenerator ilg, ExecutionContext ec);
Beispiel #7
0
 public abstract void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec);
Beispiel #8
0
 public abstract Type GetEvaluatedType(Expression left, Expression right, ExecutionContext ec);
Beispiel #9
0
 public override Type GetEvaluatedType(Expression left, Expression right, ExecutionContext ec)
 {
     throw new NotImplementedException("Non + operators are not implemented.");
 }
Beispiel #10
0
        public override Type GetEvaluatedType(Expression left, Expression right, ExecutionContext ec)
        {
            Type t = left.GetEvaluatedType(ec);
            Type t2 = right.GetEvaluatedType(ec);

            if (t != t2)
            {
                throw new NotImplementedException("Type coercion not implemented yet.");
            }

            return t; //same type because you're adding!
        }
Beispiel #11
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 #12
0
        public override Type GetEvaluatedType(ExecutionContext ec)
        {
            var arg = ec.GetParameter(name);
            if (arg != null)
            {
                return arg.Type;
            }

            var varDec = ec.GetVariable(name);
            if (varDec != null)
            {
                return varDec.LocalType;
            }

            var funcDec = Function.Get(name);
            if (funcDec != null)
            {
                return funcDec.MethodInfo.ReturnType;
            }

            //At this point, we have an unrecognized identifier

            throw new Exception("Use of undeclared identifier in expression.");
        }
Beispiel #13
0
 public override void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec)
 {
     this.fc.Push(ilg, ec);
 }
Beispiel #14
0
 public override void Push(Emit.ILGenerator ilg, ExecutionContext ec)
 {
     ilg.Emit(Emit.OpCodes.Ldstr, s);
 }
Beispiel #15
0
 public override Type GetEvaluatedType(ExecutionContext ec)
 {
     return this.o.GetEvaluatedType(left, right, ec);
 }
Beispiel #16
0
 public override Type GetEvaluatedType(ExecutionContext ec)
 {
     return Function.Get(funcName).MethodInfo.ReturnType;
 }
Beispiel #17
0
 public override void Push(Emit.ILGenerator ilg, ExecutionContext ec)
 {
     this.o.Evaluate(left, right, ilg, ec);
 }
 public ExecutionContext(ExecutionContext p)
 {
     this.parent = p;
 }
Beispiel #19
0
 public override Type GetEvaluatedType(ExecutionContext ec)
 {
     throw new NotImplementedException();
 }
Beispiel #20
0
 public override void Evaluate(Expression left, Expression right, Emit.ILGenerator ilg, ExecutionContext ec)
 {
     throw new NotImplementedException("Non + operators are not implemented.");
 }
Beispiel #21
0
 public override void Push(Emit.ILGenerator ilg, ExecutionContext ec)
 {
     throw new NotImplementedException();
 }
Beispiel #22
0
 public abstract void Evaluate(Expression left, Expression right, Emit.ILGenerator ilg, ExecutionContext ec);
Beispiel #23
0
 public abstract Type GetEvaluatedType(ExecutionContext ec);
Beispiel #24
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 #25
0
        public override void GenerateCode(Emit.ILGenerator ilg, ExecutionContext ec)
        {
            if (this.returnExp != null)
                this.returnExp.Push(ilg, ec);

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