Пример #1
0
        public void Add(STATEMENT statement)
        {
            int n = this.statements.Length;
            int i = this.length++;

            if (i == n)
            {
                STATEMENT[] new_statements = new STATEMENT[n + 8];
                for (int j = 0; j < n; j++)
                {
                    new_statements[j] = statements[j];
                }
                this.statements = new_statements;
            }
            this.statements[i] = statement;
        }
        private void generateStatement( ILGenerator il, STATEMENT statement )
        {
            if ( statement is ASSIGNMENT )
            {
                ASSIGNMENT assignment = statement as ASSIGNMENT;

                NAME left = assignment.name;
                if ( left is SELECTOR )
                {
                }
                else if ( left is ARRAY_ELEM )
                {
                }
                else // left is just NAME
                {
                    FIELD l = (left as NAME).field as FIELD;
                    if ( l.isMember )
                    {
                        FieldBuilder fb = classes[currentClass.name].fieldBuilders[l.name];
                        if ( l.isStatic )
                        {
                            generateExpression(il,assignment.expression);
                            il.Emit(OpCodes.Stsfld,fb);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldarg_0);
                            generateExpression(il,assignment.expression);
                            il.Emit(OpCodes.Stfld,fb);
                        }
                    }
                    else if ( l.isLocal )
                    {
                        generateExpression(il,assignment.expression);
                        il.Emit(OpCodes.Stloc,l.number);
                    }
                    else if ( l.isParameter )
                    {
                        int off = currentMethod.isStatic ? 0 : 1;
                        generateExpression(il,assignment.expression);
                        il.Emit(OpCodes.Starg,l.number+off);
                    }
                }
                return;
            }
            if ( statement is CALL )
            {
                MethodBuilder methodBuilder = null;
                METHOD method = null;

                CALL call = statement as CALL;

                NAME callee = call.name;
                if ( callee is SELECTOR )
                {
                    SELECTOR selector = callee as SELECTOR;
                    if (selector.field is FIELD)
                    {
                        // Access to the member of an object

                        // 1. Loading the object itself
                        FIELD obj = selector.field as FIELD;
                        if (obj.isLocal) il.Emit(OpCodes.Ldloc, obj.number);
                        else if ( obj.isParameter )
                        {
                            int off = currentMethod.isStatic ? 0 : 1;
                            il.Emit(OpCodes.Ldarg, obj.number+off);
                        }
                        else if (obj.isMember)
                        {
                            if (obj.isStatic)
                                il.Emit(OpCodes.Ldsfld, classes[currentClass.name].fieldBuilders[obj.name]);
                            else
                            {
                                il.Emit(OpCodes.Ldarg_0);
                                il.Emit(OpCodes.Ldfld, classes[currentClass.name].fieldBuilders[obj.name]);
                            }
                        }
                        // 2. Taking the method
                        method = selector.member as METHOD;
                        if ( method == null )
                        {
                            errors.issue(31);
                            return;
                        }
                        else
                            methodBuilder = classes[currentClass.name].methodBuilders[method.name];
                    }
                    else if (selector.field is CLASS)
                    {
                        // Access to the static method
                        methodBuilder = classes[currentClass.name].methodBuilders[selector.sname];
                    }
                }
                else // callee is just NAME
                {
                    method = callee.field as METHOD; // method should be != null
                    if ( method == null ) errors.issue(31);
                    methodBuilder = classes[currentClass.name].methodBuilders[method.name];
                }
             // if ( !method.isStatic ) il.Emit(OpCodes.Ldarg_0);
                foreach ( EXPRESSION e in call.arguments )
                    generateExpression(il,e);
                il.Emit(OpCodes.Call,methodBuilder);
                return;
            }
            if ( statement is PRINT )
            {
                PRINT print = statement as PRINT;
                generateExpression(il,print.value);
                Type[] arg = new Type[1];
                arg[0] = typeof(int);
                MethodInfo writeLine = typeof(System.Console).GetMethod("WriteLine",arg);
                il.EmitCall(OpCodes.Call,writeLine,null);
                return;
            }
            if ( statement is IF )
            {
                IF ifStmt = statement as IF;
                Label branchFalse = il.DefineLabel();
                generateRelation(il,ifStmt.relation,branchFalse);
                generateStatement(il,ifStmt.thenPart);
                if (ifStmt.elsePart != null)
                {
                    Label branchExit = il.DefineLabel();
                    il.Emit(OpCodes.Br,branchExit);

                    il.MarkLabel(branchFalse);

                    generateStatement(il,ifStmt.elsePart);
                    il.MarkLabel(branchExit);
                }
                else
                    il.MarkLabel(branchFalse);
                return;
            }
            if ( statement is WHILE )
            {
                WHILE whileStmt = statement as WHILE;

                Label next = il.DefineLabel();
                Label exit = il.DefineLabel();

                il.MarkLabel(next);
                generateRelation(il,whileStmt.relation,exit);
                generateStatement(il,whileStmt.body);
                il.Emit(OpCodes.Br,next);
                il.MarkLabel(exit);
                return;
            }
            if ( statement is RETURN )
            {
                RETURN returnStmt = statement as RETURN;

                if ( returnStmt.result != null )
                generateExpression(il,returnStmt.result);
                il.Emit(OpCodes.Ret);
                return;
            }
            if ( statement is BLOCK )
            {
                BLOCK block = statement as BLOCK;
                foreach ( STATEMENT s in block.statements )
                    generateStatement(il,s);
            }
        }