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); } }