コード例 #1
0
 public bool InstanceOf(Reflection.Type type)
 {
     if (this == type)
     {
         return(true);
     }
     else if (Base != null)
     {
         return(Base.InstanceOf(type));
     }
     return(false);
 }
コード例 #2
0
        public static Block ParseBlock(List <Expression> expressions, bool islocal = true)
        {
            Scope lcp = null;

            if (islocal)
            {
                lcp             = locals;
                locals          = new Scope();
                locals.previous = lcp;
            }
            var        chunk = new List <Exp>();
            Expression expr;
            var        ifparts = new Stack <If>();

            for (int i = 0; i < expressions.Count; i++)
            {
                expr = expressions[i];

                if (expr.cmd == Statement.None && expr.operators is null && expr.tokens.Count == 0)
                {
                    continue;
                }

                switch (expr.cmd)
                {
                case Statement.Import:
                    Import(fpath(expr.tokens));
                    break;

                case Statement.Using:
                    Using(expr.tokens);
                    break;

                case Statement.Class:
                    var type = new Reflection.Type(expr);
                    globals.Add(type.Name, Exp.Constant(type));
                    break;

                case Statement.Cil:
                    globals.Add(expr.tokens[0].Value, Exp.Constant(ParseCil(expr.tokens)));
                    break;

                case Statement.Function:
                    ParseFunc(expr.tokens);
                    break;

                case Statement.Return:
                    chunk.Add(new Return {
                        value = ParseExp(expr)
                    });
                    break;

                case Statement.If:
                    Exp   test   = ParseExp(expr.tokens[0].Expressions[0]);
                    Block body   = ParseBlock(expr.tokens[1]);
                    If    ifthen = new If {
                        test = test, body = body
                    };
                    ifparts.Push(ifthen);

                    if (i + 1 == expressions.Count || expressions[i + 1].cmd != Statement.Else)
                    {
                        chunk.Add(IfThenElse(ifparts));
                    }

                    break;

                case Statement.Else:
                    if (expr.tokens[0].Type == TokenType.Parenthesis)     // else if
                    {
                        goto case Statement.If;
                    }
                    else     // else
                    {
                        body = ParseBlock(expr.tokens[0]);
                        chunk.Add(IfThenElse(ifparts, body));
                    }
                    break;

                case Statement.For:
                    Token paren = expr.tokens[0];
                    if (paren.Expressions.Count == 3)
                    {
                        Exp init = ParseExp(paren.Expressions[0]);
                        chunk.Add(init);
                        test = ParseExp(paren.Expressions[1]);
                        Exp step = ParseExp(paren.Expressions[2]);
                        body = ParseBlock(expr.tokens[1]);
                        var loop = new While {
                            test = test, body = body, step = step
                        };
                        chunk.Add(loop);
                    }
                    else if (paren.Expressions.Count == 1)
                    {
                        var forEach = new ForEach();
                        forEach.var        = (Variable)ParseExp(paren.Expressions[0].operands[0]);
                        forEach.collection = ParseExp(paren.Expressions[0].tokens);
                        forEach.body       = ParseBlock(expr.tokens[1]);
                        chunk.Add(forEach);
                    }
                    break;

                case Statement.While:
                    chunk.Add(new While
                    {
                        test = ParseExp(expr.tokens[0].Expressions[0]),
                        body = ParseBlock(expr.tokens[1])
                    });
                    break;

                case Statement.Break:
                    chunk.Add(new Break());
                    break;

                case Statement.Continue:
                    chunk.Add(new Continue());
                    break;

                case Statement.Switch:
                {
                    var cases       = new List <SwitchCase>();
                    Exp switchValue = ParseExp(expr.tokens[0].Expressions[0]);

                    Exp  caseValue   = null;
                    var  bodybuilder = new List <Expression>();
                    bool jump        = true;

                    foreach (Expression e in expr.tokens[1].Expressions)
                    {
                        if (e.cmd == Statement.Case)
                        {
                            if (caseValue != null)
                            {
                                cases.Add(new SwitchCase
                                    {
                                        test = caseValue,
                                        body = ParseBlock(bodybuilder)
                                    });
                            }
                            // new case
                            caseValue = ParseExp(e);
                            if (jump)
                            {
                                if (!(caseValue is Constant))
                                {
                                    jump = false;
                                }
                            }
                            bodybuilder = new List <Expression>();
                        }
                        else
                        {
                            bodybuilder.Add(e);
                        }
                    }

                    cases.Add(new SwitchCase
                        {
                            test = caseValue,
                            body = ParseBlock(bodybuilder)
                        });

                    // try convert to jumptable
                    if (jump)
                    {
                        var table = new Dictionary <dynamic, Block>();
                        foreach (SwitchCase c in cases)
                        {
                            table.Add(((Constant)c.test).value, c.body);
                        }
                        chunk.Add(new JumpTable {
                                value = switchValue, table = table
                            });
                    }
                    else
                    {
                        chunk.Add(new Switch {
                                switchValue = switchValue, cases = cases.ToArray()
                            });
                    }
                    break;
                }

                case Statement.Echo:
                    Exp msg = ParseExp(expr);
                    chunk.Add(new Invoke {
                        obj = Exp.Echo, arg = new[] { msg }
                    });
                    break;

                case Statement.Throw:
                    msg = ParseExp(expr);
                    chunk.Add(new Throw {
                        message = msg
                    });
                    break;

                case Statement.Var:
                    if (expr.operators is null)
                    {
                        string name = expr.tokens[0].Value;
                        locals.NewVar(name);
                    }
                    else if (expr.operators[0] == Op.Assign)
                    {
                        string name = expr.operands[0][0].Value;
                        locals.NewVar(name);
                        goto default;
                    }
                    break;

                default:
                    chunk.Add(ParseExp(expr));
                    break;
                }
            }
            if (islocal)
            {
                var body = new Block {
                    expressions = chunk
                };
                body.SetVariables();
                locals = lcp;
                return(body);
            }
            return(new Block {
                expressions = chunk
            });
        }
コード例 #3
0
        public Type(Expression source)
        {
            // get the name
            if (source.operators is null)
            {
                Name = source.tokens[0].Value;
            }
            else // extends
            {
                Name = source.operands[0][0].Value;
                Base = (Parser.globals[source.tokens[0].Value] as Constant).value;
            }
            // initializer
            var init = new List <Exp>();
            // get all members
            var        fields = new List <string>();
            Token      body   = source.tokens.Last();
            Expression expr;

            for (int i = 0; i < body.Expressions.Count; i++)
            {
                expr = body.Expressions[i];
                if (expr.operators?[0] == Op.Assign)
                {
                    string fldName = expr.operands[0][0].Value;
                    var    fi      = new FieldInfo(fldName, fldcnt++);
                    Add(fldName, fi);
                    fields.Add(fldName);
                    init.Add(Parser.ParseExp(expr));
                }
                else if (expr.cmd == Statement.Get)
                {
                    MethodInfo m = MethodInfo.Parse(expr.tokens, fields);
                    if (TryGetValue(m.Name, out IMember value))
                    {
                        var prop = (PropertyInfo)value;
                        prop.GetMethod = m;
                    }
                    else
                    {
                        var prop = new PropertyInfo();
                        prop.Name      = m.Name;
                        prop.GetMethod = m;
                        Add(m.Name, prop);
                    }
                }
                else if (expr.cmd == Statement.Set)
                {
                    MethodInfo m = MethodInfo.Parse(expr.tokens, fields);
                    if (TryGetValue(m.Name, out IMember value))
                    {
                        var prop = (PropertyInfo)value;
                        prop.SetMethod = m;
                    }
                    else
                    {
                        var prop = new PropertyInfo();
                        prop.Name      = m.Name;
                        prop.SetMethod = m;
                        Add(m.Name, prop);
                    }
                }
                else if (expr.operators is null &&
                         expr.tokens.Count == 3 &&
                         expr.tokens[0].Type == TokenType.Identifier &&
                         expr.tokens[1].Type == TokenType.Parenthesis &&
                         expr.tokens[2].Type == TokenType.Braces)
                {
                    MethodInfo m = MethodInfo.Parse(expr.tokens, fields);
                    if (m.Name == "constructor")
                    {
                        ctor = m;
                    }
                    else
                    {
                        Add(m.Name, m);
                    }
                }
            }
            // embed field initialization into constructor
            if (ctor is null)
            {
                ctor      = new MethodInfo();
                ctor.body = new Block {
                    expressions = new List <Exp>(), lcsize = 1
                };
                ctor.self = new Variable {
                    block = ctor.body
                };
            }
            // initialize field values
            for (int i = 0; i < fields.Count; i++)
            {
                var assign = (Operation.Assign)init[i];
                assign.left = Exp.Member(ctor.self, fields[i]);
                ctor.body.expressions.Insert(i, assign);
            }
        }