コード例 #1
0
        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
        }
コード例 #2
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     expression1.resolve(p,c,m);
     expression2.resolve(p,c,m);
 }
コード例 #3
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     if ( result == null ) return;
     result.resolve(p,c,m);
 }
コード例 #4
0
 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);
 }
コード例 #5
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     foreach ( CLASS cls in classes.Values )
         cls.resolve(this,null,null);
 }
コード例 #6
0
 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);
 }
コード例 #7
0
        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));
        }
コード例 #8
0
 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);
 }
コード例 #9
0
 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);
         }
     }
 }
コード例 #10
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     if ( type == null ) return;
     type.resolve(p,c,m);
 }
コード例 #11
0
 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);
 }
コード例 #12
0
 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);
 }
コード例 #13
0
 public virtual void resolve(PROGRAM p, CLASS c, METHOD m)
 {
 }
コード例 #14
0
 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;
 }
コード例 #15
0
 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);
 }
コード例 #16
0
 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);
 }
コード例 #17
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     foreach ( STATEMENT s in statements )
         s.resolve(p,c,m);
 }
コード例 #18
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     base.resolve(p,c,m);
     size.resolve(p,c,m);
 }
コード例 #19
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     relation.resolve(p,c,m);
     body.resolve(p,c,m);
 }
コード例 #20
0
 public override void resolve(PROGRAM p, CLASS c, METHOD m)
 {
     value.resolve(p,c,m);
 }
コード例 #21
0
        /// <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;
        }
コード例 #22
0
 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);
 }