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)
 {
     expression1.resolve(p,c,m);
     expression2.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)
 {
     value.resolve(p,c,m);
 }
 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)
 {
     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)
 {
     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)
 {
     term.resolve(p,c,m);
     foreach ( TERM t in terms )
         t.resolve(p,c,m);
 }
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     if ( type == null ) return;
     type.resolve(p,c,m);
 }
 public virtual void resolve(PROGRAM p, CLASS c, METHOD m)
 {
 }
 public METHOD findMethodInClass(CLASS cls, string name)
 {
     if ( cls.methods.ContainsKey(name) ) return cls.methods[name];
     return null;
 }
 public FIELD findFieldInClass(CLASS cls, string name)
 {
     if ( cls.fields.ContainsKey(name) ) return cls.fields[name];
     return null;
 }
 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 ( 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)
        {
            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)
 {
     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)
 {
     foreach ( STATEMENT s in statements )
         s.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)
 {
     relation.resolve(p,c,m);
     body.resolve(p,c,m);
 }
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     base.resolve(p,c,m);
     size.resolve(p,c,m);
 }
        /// <summary>
        /// ClassDeclaration ::= ["public"] "class" Identifier ["extends" Identifier] 
        ///                      "{" { FieldDeclaration | MethodDeclaration } "}".
        /// </summary>
        /// <returns></returns>
        private CLASS parseClassDeclaration()
        {
            int pub = 1;
            string className = null;
            string baseName = null;

            Token token = lexer.get();
            if ( token.code == TokenCode.EOF ) // end of compilation unit
                return null;

            if ( token.code == TokenCode.PUBLIC ) { lexer.forget(); pub = 0; }

            token = lexer.get();
            if ( token.code == TokenCode.CLASS )  { lexer.forget(); }
            else                                  { errors.issue(token,11,"class"); lexer.skipUntil(TokenCode.LBRACE); }

            token = lexer.get();
            if ( token.code == TokenCode.IDENTIFIER ) { className = token.image; lexer.forget(); }
            else                                      { errors.issue(token,11,"identifier"); lexer.skipUntil(TokenCode.LBRACE); }

            token = lexer.get();
            if ( token.code == TokenCode.IMPORT )
            {
                lexer.forget();
                token = lexer.get();
                if ( token.code == TokenCode.IDENTIFIER ) { baseName = token.image; lexer.forget(); }
                else                                      { errors.issue(token,11,"identifier"); lexer.skipUntil(TokenCode.LBRACE); }
            }

            CLASS result = new CLASS(pub,className,baseName);

            token = lexer.get();
            if ( token.code == TokenCode.LBRACE )
            {
                lexer.forget();
                while ( true )
                {
                    DECLARATION member = parseMethodOrField();
                    if ( member == null ) break;
                    string n = member.name;
                    if ( member is FIELD )
                    {
                        (member as FIELD).isMember = true;
                        if ( result.fields.ContainsKey(n) )
                            errors.issue(token,12,"field",n); // duplicating field declaration
                        else
                            result.fields.Add(n,member as FIELD);
                    }
                    else // member is METHOD
                    {
                        if ( result.methods.ContainsKey(n) )
                            errors.issue(token,12,"method",n); // duplicatin method declaration
                        else
                            result.methods.Add(n,member as METHOD);
                    }
                }
            }
            else
            {
                errors.issue(token,11,"{");
                lexer.skipUntil(TokenCode.RBRACE);
            }
            return result;
        }
 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);
 }