public override void resolve(PROGRAM p, CLASS c, METHOD m) { base.resolve(p,c,m); if ( field == null ) return; // error was detected if ( field is FIELD ) { FIELD f = field as FIELD; f.type.resolve(p,c,m); if ( f.type.classRef != null ) { member = findFieldInClass(f.type.classRef,sname); if ( member == null ) member = findMethodInClass(f.type.classRef,sname); if ( member == null ) p.errors.issue(21,"field or method",sname); if ( member != null ) { if ( member.isStatic ) p.errors.issue(26,member.name); if ( member.isPrivate ) p.errors.issue(27,member,name); // access violation } } else // a non-class variable in selector p.errors.issue(25); } else if ( field is CLASS ) { CLASS cls = field as CLASS; member = findFieldInClass(cls,sname); if ( member == null ) member = findMethodInClass(cls,sname); if ( member == null ) p.errors.issue(21,"field or method",name); if ( member != null ) { if ( !member.isStatic ) p.errors.issue(24,member.name); if ( member.isPrivate ) p.errors.issue(27,member.name); // access violation } } else if ( field is METHOD ) p.errors.issue(25); // a method in the left part of the selector }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { expression1.resolve(p,c,m); expression2.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if ( result == null ) return; result.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if ( bname != null ) { baseClass = findClass(p,bname); if ( baseClass == null ) p.errors.issue(21,"base class"); } foreach ( FIELD f in fields.Values ) f.resolve(p,this,null); foreach ( METHOD meth in methods.Values ) meth.resolve(p,this,null); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { foreach ( CLASS cls in classes.Values ) cls.resolve(this,null,null); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if (classRef != null) return; // already resolved if (className == "int") return; // not necessary to resolve classRef = findClass(p,className); if ( classRef == null ) p.errors.issue(21,"class",className); }
public void generateProgram() { AppDomain ad = System.Threading.Thread.GetDomain(); AssemblyName an = new AssemblyName(); an.Name = Path.GetFileNameWithoutExtension(source.fileName); AssemblyBuilder ab = ad.DefineDynamicAssembly(an,AssemblyBuilderAccess.RunAndSave); ModuleBuilder modb = ab.DefineDynamicModule(an.Name,an.Name+".exe",true); modb.CreateGlobalFunctions(); // Preparing classes foreach ( CLASS cls in program.classes.Values ) { TypeAttributes classAttrs = cls.isPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; TypeBuilder typeBuilder = modb.DefineType(cls.name,classAttrs); classes[cls.name] = new ClassStructure(); classes[cls.name].typeBuilder = typeBuilder; classes[cls.name].methodBuilders = new Dictionary<string,MethodBuilder>(); classes[cls.name].fieldBuilders = new Dictionary<string,FieldBuilder>(); // Preparing default constructors for the class Type[] ctorTypes = new Type[0]; ConstructorBuilder ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.RTSpecialName, CallingConventions.Standard, ctorTypes); classes[cls.name].ctorBuilder = ctorBuilder; // IL_0000: ldarg.0 // IL_0001: call instance void [mscorlib]System.Object::.ctor() // IL_0006: ret ILGenerator ctorIL = ctorBuilder.GetILGenerator(); ctorIL.Emit(OpCodes.Ldarg_0); Type[] ctorArgs = new Type[0]; ConstructorInfo ctor = typeof(System.Object).GetConstructor(ctorArgs); ctorIL.Emit(OpCodes.Call,ctor); ctorIL.Emit(OpCodes.Ret); // Preparing methods in the class foreach ( METHOD method in cls.methods.Values ) { MethodAttributes methodAttrs = method.isPublic ? MethodAttributes.Public : MethodAttributes.Private; if ( method.isStatic ) methodAttrs |= MethodAttributes.Static; Type resType = null; if (method.type == null) resType = typeof(void); else { TYPE t = method.type; if ( t.classRef == null ) resType = typeof(int); else resType = classes[method.type.className].typeBuilder; } Type[] parTypes = new Type[method.parameters.Count]; int i = 0; foreach (FIELD par in method.parameters.Values) { TYPE t = par.type; Type parType = null; if ( t.classRef == null ) parType = typeof(int); else parType = classes[t.className].typeBuilder; parTypes[i] = parType; i++; } MethodBuilder mb = typeBuilder.DefineMethod(method.name,methodAttrs,resType,parTypes); classes[cls.name].methodBuilders.Add(method.name,mb); } // Generating class fields foreach ( FIELD field in cls.fields.Values ) { TYPE t = field.type; Type type = null; if ( t.classRef == null ) { if ( t.isArray ) type = typeof(int[]); else type = typeof(int); } else { type = classes[t.className].typeBuilder; if ( t.isArray ) type = type.MakeArrayType(); } FieldAttributes attrs = field.isPublic ? FieldAttributes.Public : FieldAttributes.Private; if ( field.isStatic ) attrs |= FieldAttributes.Static; FieldBuilder fb = typeBuilder.DefineField(field.name,type,attrs); classes[cls.name].fieldBuilders.Add(field.name,fb); } } // Generating class bodies foreach ( CLASS cls in program.classes.Values ) { TypeBuilder typeBuilder = classes[cls.name].typeBuilder; currentClass = cls; // Generating bodies of class methods foreach ( METHOD method in cls.methods.Values ) { currentMethod = method; MethodBuilder methodBuilder = classes[cls.name].methodBuilders[method.name]; ILGenerator il = methodBuilder.GetILGenerator(); // Generating method locals foreach ( FIELD field in method.locals.Values ) generateLocal(il,field); // Generating method's bodies STATEMENT last = null; foreach ( STATEMENT statement in method.statements ) { generateStatement(il,statement); last = statement; } if ( !(last is RETURN) && method.type == null ) il.Emit(OpCodes.Ret); // Defining the program entry point if ( method.name == "Main" && method.isStatic ) ab.SetEntryPoint(methodBuilder); } typeBuilder.CreateType(); } // Saving the assembly ab.Save(Path.GetFileName(source.targetName)); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if ( type != null ) type.resolve(p,c,m); foreach ( FIELD f in parameters.Values ) f.resolve(p,c,this); foreach ( FIELD f in locals.Values ) f.resolve(p,c,this); foreach ( STATEMENT s in statements ) s.resolve(p,c,this); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if ( m != null ) field = findFieldInMethod(m,name); if ( field == null && c != null ) field = findFieldInClass(c,name); if ( field == null && c != null ) field = findMethodInClass(c,name); if ( field == null ) p.errors.issue(21,"name",name); else { FIELD f = field as FIELD; if ( f != null && (f.isLocal || f.isParameter) ) return; if ( field is FIELD || field is METHOD ) { if ( field.isStatic && !m.isStatic ) p.errors.issue(28,field.name); if ( !field.isStatic && m.isStatic ) p.errors.issue(29,field.name); } } }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if ( type == null ) return; type.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { relation.resolve(p,c,m); thenPart.resolve(p,c,m); elsePart.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { term.resolve(p,c,m); foreach ( TERM t in terms ) t.resolve(p,c,m); }
public virtual void resolve(PROGRAM p, CLASS c, METHOD m) { }
public FIELD findFieldInMethod(METHOD method, string name) { if ( method.locals.ContainsKey(name) ) return method.locals[name]; if ( method.parameters.ContainsKey(name) ) return method.parameters[name]; return null; }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { factor.resolve(p,c,m); foreach ( FACTOR f in factors ) f.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { if (name == null) return; // new int classRef = findClass(p,name); if (classRef == null) p.errors.issue(21,"class",name); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { foreach ( STATEMENT s in statements ) s.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { base.resolve(p,c,m); size.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { relation.resolve(p,c,m); body.resolve(p,c,m); }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { value.resolve(p,c,m); }
/// <summary> /// FieldDeclaration ::= [Visibility] ["static"] Type Identifier ";". /// /// MethodDeclaration ::= [Visibility] ["static"] ("void" | Type) Identifier /// "("[Parameter {"," Parameter}] ")" Body. /// /// Visibility ::= "private" | "public" | "private". /// /// Parameter ::= Type Identifier. /// /// Body ::= "{" {LocalDeclaration} {Statement} "}". /// /// LocalDeclaration ::= Type Identifier ";". /// </summary> /// <returns></returns> private DECLARATION parseMethodOrField() { int v = 0; bool s = false; string name = null; Token token = lexer.get(); if ( token.code == TokenCode.RBRACE ) // end of class methods { lexer.forget(); return null; } switch ( token.code ) { case TokenCode.PUBLIC : v = 0; lexer.forget(); break; case TokenCode.PRIVATE : v = 1; lexer.forget(); break; case TokenCode.PROTECTED : v = 2; lexer.forget(); break; default: v = 0; break; } token = lexer.get(); if ( token.code == TokenCode.STATIC ) { s = true; lexer.forget(); } TYPE type = null; token = lexer.get(); if ( token.code == TokenCode.VOID ) lexer.forget(); else type = parseType(); token = lexer.get(); if ( token.code == TokenCode.IDENTIFIER ) { name = token.image; lexer.forget(); } else errors.issue(token,11,"identifier"); token = lexer.get(); if ( token.code == TokenCode.SEMICOLON ) { // End of field declaration lexer.forget(); if ( type == null ) errors.issue(token,14); // void in field declaration FIELD field = new FIELD(v,name); field.type = type; field.isStatic = s; return field; } // Else this is a method declaration. METHOD method = new METHOD(v, name); method.isStatic = s; method.type = type; if ( name == "Main" ) { if ( hasMain ) errors.issue(token,32); // multiple Main's else hasMain =true; } // Continue parsing: // "(" [ Parameter {"," Parameter} ] ")" Body token = lexer.get(); if ( token.code != TokenCode.LPAREN ) { errors.issue(token,11,"("); lexer.skipUntil(TokenCode.RPAREN); } else lexer.forget(); int i = 0; while ( true ) // parsing method parameters { token = lexer.get(); if ( token.code == TokenCode.RPAREN ) { lexer.forget(); break; } FIELD parameter = parseParameter(); string n = parameter.name; if ( method.parameters.ContainsKey(n) ) errors.issue(token,12,"parameter",n); else { parameter.number = i; i++; method.parameters.Add(n,parameter); } token = lexer.get(); if (token.code == TokenCode.COMMA) { lexer.forget(); continue; } else if (token.code != TokenCode.RPAREN) { errors.issue(token,16); lexer.skipUntil(TokenCode.RPAREN); lexer.forget(); break; } } // Parsing method body: // // Body ::= "{" {LocalDeclaration} {Statement} "}". token = lexer.get(); if ( token.code == TokenCode.LBRACE ) lexer.forget(); else lexer.skipUntil(TokenCode.RBRACE); int j = 0; while ( true ) { token = lexer.get(); if ( token.code == TokenCode.RBRACE ) { lexer.forget(); break; } ENTITY bodyElement = parseBodyElement(); if ( bodyElement == null ) // and error was detected continue; else if ( bodyElement is FIELD ) { (bodyElement as FIELD).isLocal = true; string n = (bodyElement as FIELD).name; if ( method.locals.ContainsKey(n) ) errors.issue(token,12,"local",n); else { (bodyElement as FIELD).number = j; j++; method.locals.Add(n,bodyElement as FIELD); } } else if ( bodyElement is STATEMENT ) method.statements.Add(bodyElement as STATEMENT); } return method; }
public override void resolve(PROGRAM p, CLASS c, METHOD m) { name.resolve(p,c,m); foreach ( EXPRESSION a in arguments ) a.resolve(p,c,m); }