コード例 #1
0
ファイル: CodeGen.cs プロジェクト: ypyf/Clound
 private Type TypeOfExpr(Expr expr, Env table)
 {
     if (expr is StrLiteral)
     {
         return(typeof(string));
     }
     else if (expr is IntLiteral)
     {
         return(typeof(int));
     }
     else if (expr is Variable)
     {
         Variable var = (Variable)expr;
         if (table.HasInstance(var.Name))
         {
             return(table[var.Name].SymbolType);
         }
         else
         {
             throw new Exception("undeclared variable '" + var.Name + "'");
         }
     }
     else if (expr is BoolLiteral)
     {
         return(typeof(bool));
     }
     else if (expr is CallExpr)
     {
         // TODO 检查函数类型
         return(typeof(object));
     }
     else if (expr is MemberAccessExpr)
     {
         MemberAccessExpr mae = (MemberAccessExpr)expr;
         return(TypeOfExpr(mae.Postfix, table));
     }
     else if (expr is PrimaryExpr)
     {
         PrimaryExpr pe = (PrimaryExpr)expr;
         return(TypeOfExpr(pe.Postfix, table));
     }
     //else if (expr is Undefined)
     //{
     //    return typeof(object);
     //}
     else
     {
         throw new Exception("don't know how to calculate the type of " + expr.GetType().Name);
     }
 }
コード例 #2
0
        //primary := ( "(" <expr> ")" | INT | STRING | BOOL | IDENTIFIER ) { <postfix> }
        private Expr primary()
        {
            PrimaryExpr exp = new PrimaryExpr();

            if (IsToken("("))
            {
                EatToken();
                exp.Lhs = ParseExpr();
                Match(")");
            }
            else if (lookahead is IntToken)
            {
                IntLiteral n = new IntLiteral();
                n.Value = int.Parse(lookahead.Text);
                EatToken();
                exp.Lhs = n;
            }
            else if (lookahead is StrToken)
            {
                StrLiteral n = new StrLiteral();
                n.Value = lookahead.Text;
                EatToken();
                exp.Lhs = n;
            }
            else if (lookahead is IdentToken)
            {
                if (IsToken("true"))
                {
                    EatToken();
                    BoolLiteral boolLiteral = new BoolLiteral();
                    boolLiteral.Value = 1;
                    exp.Lhs           = boolLiteral;
                }
                else if (IsToken("false"))
                {
                    EatToken();
                    BoolLiteral boolLiteral = new BoolLiteral();
                    boolLiteral.Value = 0;
                    exp.Lhs           = boolLiteral;
                }
                else
                {
                    string ident = lookahead.Text;
                    EatToken();
                    Variable var = new Variable();
                    var.Name = ident;
                    exp.Lhs  = var;
                }
            }
            else if (IsDelimiter())
            {
                // 空表达式
                exp.Lhs = Expr.Undefined;
            }
            else
            {
                throw new Exception("syntax error: unrecognized expression");
            }

            exp.Postfix = Postfix();
            if (exp.Postfix == null)
            {
                return(exp.Lhs);
            }
            return(exp);
        }
コード例 #3
0
ファイル: CodeGen.cs プロジェクト: ypyf/Clound
        private void GenExpr(Expr expr, Env table, ILGenerator il)
        {
            if (expr is StrLiteral)
            {
                il.Emit(OpCodes.Ldstr, ((StrLiteral)expr).Value);
            }
            else if (expr is IntLiteral)
            {
                il.Emit(OpCodes.Ldc_I4, ((IntLiteral)expr).Value);
            }
            else if (expr is BoolLiteral)
            {
                il.Emit(OpCodes.Ldc_I4, ((BoolLiteral)expr).Value);
            }
            else if (expr is Variable)
            {
                string name = ((Variable)expr).Name;
                Load(name, table, il);
            }
            else if (expr is PrimaryExpr)
            {
                PrimaryExpr pe = (PrimaryExpr)expr;
                //GenExpr(pe.Lhs, table, il);
                if (pe.Lhs is Variable) // LHS此时可能是命名空间、类型名、实例变量(包括函数名)等
                {
                    string name = ((Variable)pe.Lhs).Name;
                    if (pe.Postfix is CallExpr)
                    {
                        // TODO 目前不考虑链式调用
                        CallExpr ce = (CallExpr)pe.Postfix;
                        // 函数调用
                        if (globalFunctions.ContainsKey(name))
                        {
                            // 载入参数
                            foreach (var arg in ce.Args)
                            {
                                GenExpr(arg, table, il);
                            }
                            // 调用函数
                            Reflect.MethodInfo mi = globalFunctions[name];
                            il.Emit(OpCodes.Call, mi);
                        }
                        else if (table.HasInstance(name))
                        {
                            throw new Exception(String.Format("'{0}'是变量,不是函数", name));
                        }
                        else
                        {
                            throw new Exception(String.Format("当前上下文中不存在名称'{0}'", name));
                        }
                    }
                    else if (pe.Postfix is MemberAccessExpr)
                    {
                        // 目前只实现了导入模块,还没有实现Class
                        MemberAccessExpr mae = (MemberAccessExpr)pe.Postfix;
                        if (mae.Postfix is MemberAccessExpr)
                        {
                            string ns = ns = name + "." + mae.Ident;;
                            // 合并命名空间(CLR的类型名在运行时是命名空间的一部分)
                            PrimaryExpr exp = new PrimaryExpr();
                            Variable    var = new Variable();
                            var.Name    = ns;
                            exp.Lhs     = var;
                            exp.Postfix = mae.Postfix;
                            // 递归生成合并后的表达式
                            GenExpr(exp, table, il);
                        }
                        else if (mae.Postfix is CallExpr)
                        {
                            // 调用C#模块中的方法
                            CallExpr ce = (CallExpr)mae.Postfix;

                            // 在所有模块中间查找类型和方法
                            Type type = FirstMatchType(name, table);
                            if (type != null)
                            {
                                // 载入参数
                                List <Type> typelist = new List <Type>();
                                foreach (var arg in ce.Args)
                                {
                                    typelist.Add(TypeOfExpr(arg, table));
                                    GenExpr(arg, table, il);
                                }
                                // 调用函数
                                Reflect.MethodInfo mi = type.GetMethod(mae.Ident, typelist.ToArray());
                                if (mi != null)
                                {
                                    il.Emit(OpCodes.Call, mi);
                                }
                                else
                                {
                                    throw new Exception(String.Format("方法{0}未发现", mae.Ident));
                                }
                            }
                            else
                            {
                                throw new Exception(String.Format("类型{0}未发现", name));
                            }
                        }
                        else
                        {
                            //此时 Postfix == null
                            // 访问属性
                            // 例如 a.Length
                            throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    // TODO OO语言中,可以考虑在字面量上访问方法
                    // 例如 10.to_s() => "10"
                    throw new NotImplementedException();
                }
            }
            else if (expr is BinaryExpr)
            {
                BinaryExpr be = (BinaryExpr)expr;
                // 赋值
                if (be.Op.Equals("="))
                {
                    GenExpr(be.Right, table, il);
                    if (be.Left is Variable)
                    {
                        Store(((Variable)be.Left).Name, table, il);
                    }
                    else
                    {
                        throw new Exception("except a lvalue at assign");
                    }
                }
                else
                {
                    // 算术运算
                    // FIXME IL没有一些条件运算,需要单独提出来实现
                    GenExpr(be.Left, table, il);
                    GenExpr(be.Right, table, il);
                    switch (be.Op)
                    {
                    case "+":
                        il.Emit(OpCodes.Add);
                        break;

                    case "-":
                        il.Emit(OpCodes.Sub);
                        break;

                    case "*":
                        il.Emit(OpCodes.Mul);
                        break;

                    case "/":
                        il.Emit(OpCodes.Div);
                        break;

                    case "%":
                        il.Emit(OpCodes.Rem);
                        break;

                    case "<":
                        il.Emit(OpCodes.Clt);
                        break;

                    case ">":
                        il.Emit(OpCodes.Cgt);
                        break;

                    case "==":
                        il.Emit(OpCodes.Ceq);
                        break;

                    case "<=":
                    //il.Emit(OpCodes.Cgt);   // FIXME
                    //break;
                    case ">=":
                    //il.Emit(OpCodes.Clt);   // FIXME
                    //break;
                    case "!=":
                    //il.Emit(OpCodes.Ceq);   // FIXME
                    //break;
                    default:
                        throw new Exception("Unrecognized operator: " + be.Op);
                    }
                }
            }
            else if (expr is Undefined)
            {
                return;
            }
            else
            {
                throw new Exception("don't know how to generate " + expr.GetType().Name);
            }
        }