示例#1
0
        //- declarations --------------------------------------------------------

        public void makeDeclarationNode(DeclSpecNode declarspecs, DeclaratorNode declarator, InitializerNode initializer)
        {
            VarDeclNode vardecl = new VarDeclNode();

            vardecl.varType = declarspecs.baseType;
            DeclaratorNode dnode = declarator;

            while (dnode != null)
            {
                if (dnode is IdentDeclaratorNode)
                {
                    vardecl.name = ((IdentDeclaratorNode)dnode).ident;
                }
                dnode = dnode.next;
            }
            vardecl.initializer = initializer;
            symbolTable.addSymbol(vardecl.name, vardecl);

            //add decl to either global or local decl list
            if (curFunc != null)
            {
                curFunc.locals.Add(vardecl);
            }
            else
            {
                curModule.globals.Add(vardecl);
            }

            if (initializer != null && curBlock != null)
            {
                DeclarInitStatementNode dstmt = new DeclarInitStatementNode(vardecl, initializer.initExpr);
                addStmtToBlock(dstmt);
                vardecl.initializer = null;
            }
        }
示例#2
0
 public override void VisitVarDeclNode(VarDeclNode node)
 {
     foreach(DelimitedItemNode<Token> delimitedItemNode in node.NameListNode.Items) {
         Token nameToken = delimitedItemNode.ItemNode;
         AddHit(nameToken, nameToken.Text);
     }
     base.VisitVarDeclNode(node);
 }
示例#3
0
 public void Visit(VarDeclNode n)
 {
     foreach (var node in n.GetChildren())
     {
         node.SymTable = n.SymTable;
         node.Accept(this);
     }
 }
示例#4
0
 public void Visit(VarDeclNode n)
 {
     PrintDOTIDLabel(n);
     PrintDOTParentChild(n);
     foreach (var child in n.GetChildren())
     {
         child.Accept(this);
     }
 }
 public override void VisitVarDeclNode(VarDeclNode node)
 {
     foreach (DelimitedItemNode <Token> delimitedItemNode in node.NameListNode.Items)
     {
         Token nameToken = delimitedItemNode.ItemNode;
         AddHit(nameToken, nameToken.Text);
     }
     base.VisitVarDeclNode(node);
 }
 public static DeclaredSymbol From(DeclSpecsNode specs, DeclNode decl)
 {
     return(decl switch
     {
         VarDeclNode var => new DeclaredVariableSymbol(decl.Identifier, specs, var, var.Initializer),
         ArrDeclNode arr => new DeclaredArraySymbol(decl.Identifier, specs, arr, arr.SizeExpression, arr.Initializer),
         FuncDeclNode f => new DeclaredFunctionSymbol(decl.Identifier, specs, f),
         _ => throw new NotImplementedException("Declarator node type not yet implemented"),
     });
示例#7
0
        public void Visit(VarDeclNode n)
        {
            var children = n.GetChildren();

            foreach (var child in children)
            {
                child.Accept(this);
            }
        }
示例#8
0
 public VarDeclNode buildInitDeclarator(OILNode node1, OILNode node2)
 {
     if (node1 != null)
     {
         VarDeclNode node = (VarDeclNode)node1;
         node.initializer = (InitializerNode)node2;
         return(node);
     }
     return(null);
 }
示例#9
0
 public virtual void VisitVarDeclNode(VarDeclNode node)
 {
     Visit(node.NameListNode);
     Visit(node.ColonNode);
     Visit(node.TypeNode);
     Visit(node.FirstPortabilityDirectiveListNode);
     Visit(node.AbsoluteSemikeywordNode);
     Visit(node.AbsoluteAddressNode);
     Visit(node.EqualSignNode);
     Visit(node.ValueNode);
     Visit(node.SecondPortabilityDirectiveListNode);
     Visit(node.SemicolonNode);
 }
示例#10
0
 public OILNode buildBaseDirectDeclarator(Token id, OILNode node1)
 {
     if (id != null)
     {
         VarDeclNode node = new VarDeclNode();
         //node.name = id.strval;
         return(node);
     }
     if (node1 != null)
     {
         return(new OILNode());
     }
     return(null);
 }
示例#11
0
        private ClassDeclNode ParseEnumType(Type type, string alias)
        {
            //TODO: For now Enum can't be suppressed.
            Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (f.FieldType != type)
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                variable.IsStatic = true;
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    func.IsStatic = true;
                    RegisterFunctionPointer(func.Name, f, null, func.ReturnType);
                    classnode.funclist.Add(func);
                }
            }

            //Get all the attributes on this type and set it to the classnode.
            FFIClassAttributes cattrs = new FFIClassAttributes(type);

            classnode.ClassAttributes = cattrs;
            SetTypeAttributes(type, cattrs);

            return(classnode);
        }
示例#12
0
        protected void AssertVariableDeclaration(string src,
                                                 string identifier,
                                                 string type,
                                                 AccessModifiers access    = AccessModifiers.Unspecified,
                                                 QualifierFlags qualifiers = QualifierFlags.None,
                                                 object?value = null)
        {
            DeclStatNode decl = this.AssertDeclarationNode(src, type, access, qualifiers);

            Assert.That(decl.DeclaratorList.Parent, Is.EqualTo(decl));
            VarDeclNode var = decl.DeclaratorList.Declarators.Single().As <VarDeclNode>();

            Assert.That(var.Parent, Is.EqualTo(decl.DeclaratorList));
            Assert.That(var.Identifier, Is.EqualTo(identifier));
            Assert.That(var.Children.First().As <IdNode>().Identifier, Is.EqualTo(identifier));
            if (value is { })
示例#13
0
        public override Node VisitFor([NotNull] TigerParser.ForContext context)
        {
            var node = new ForNode(context);

            ITerminalNode id   = context.ID();
            var           init = new VarDeclNode(id.Symbol.Line, id.Symbol.Column, true);

            init.Children.Add(new IdNode(id.Symbol.Line, id.Symbol.Column, id.GetText())); // init -> INIT VARIABLE NAME
            init.Children.Add(null);                                                       // init -> INIT VARIABLE TYPE
            init.Children.Add(Visit(context.expr(0)));                                     // init -> INIT VARIABLE VALUE EXPRESSION

            node.Children.Add(init);                                                       // INIT VARIABLE
            node.Children.Add(Visit(context.expr(1)));                                     //TO EXPRESSION
            node.Children.Add(Visit(context.expr(2)));                                     //DO EXPRESSION

            return(node);
        }
示例#14
0
        public void genFunctions(Module module)
        {
            assembly.addLine(".section text");
            foreach (FuncDefNode func in module.funcs)
            {
                CGFuncDefNode cgfunc = new CGFuncDefNode(func);

                assembly.addLine(".global " + func.name);

                uint paramofs = 8;
                for (int i = 0; i < func.paramList.Count; i++)
                {
                    ParamDeclNode   para   = func.paramList[i];
                    CGParamDeclNode cgpara = new CGParamDeclNode(para);
                    cgpara.addr = paramofs;
                    paramofs   += 4;
                }

                //for now, the only type we handle are ints, so each local var is 4 bytes on the stack
                cgfunc.stacksize = 0;
                for (int i = 0; i < func.locals.Count; i++)
                {
                    VarDeclNode   local   = func.locals[i];
                    CGVarDeclNode cglocal = new CGVarDeclNode(local);
                    cgfunc.stacksize += 4;
                    cglocal.addr      = cgfunc.stacksize;
                    cglocal.type      = CGVarDeclNode.VarType.LOCAL;
                }

                //func prolog
                assembly.addLine(func.name + ":");
                assembly.addLine("push ebp");
                assembly.addLine("mov ebp, esp");
                assembly.addLine("sub esp, " + cgfunc.stacksize);

                foreach (StatementNode stmt in func.body)
                {
                    genStatement(stmt);
                }

                //func epilog
                assembly.addLine("mov esp, ebp");
                assembly.addLine("pop ebp");
                assembly.addLine("ret");
            }
        }
        private ClassDeclNode ParseEnumType(Type type, string alias)
        {
            Validity.Assert(type.IsEnum, "Non enum type is being imported as enum!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (f.FieldType != type)
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                variable.IsStatic = true;
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    func.IsStatic = true;
                    RegisterFunctionPointer(func.Name, f, func.ReturnType);
                    classnode.funclist.Add(func);
                }
            }

            return(classnode);
        }
示例#16
0
        public override Node VisitVarDecl([NotNull] TigerParser.VarDeclContext context)
        {
            var node = new VarDeclNode(context);

            node.Children.Add( // NAME
                new IdNode(
                    context.id.Line,
                    context.id.Column,
                    context.id.Text));

            node.Children.Add(context.typeId == null ? // TYPE
                              null :
                              new IdNode(
                                  context.typeId.Line,
                                  context.typeId.Column,
                                  context.typeId.Text));

            node.Children.Add(Visit(context.expr())); // EXPRESSION
            return(node);
        }
示例#17
0
        private static FunctionDefinitionNode GenerateBuiltInMethodSignatureNode(Lang.BuiltInMethods.BuiltInMethod method)
        {
            FunctionDefinitionNode fDef = new FunctionDefinitionNode();

            fDef.Name             = Lang.BuiltInMethods.GetMethodName(method.ID);
            fDef.ReturnType       = method.ReturnType;
            fDef.IsExternLib      = true;
            fDef.IsBuiltIn        = true;
            fDef.BuiltInMethodId  = method.ID;
            fDef.Signature        = new ArgumentSignatureNode();
            fDef.MethodAttributes = method.MethodAttributes;

            foreach (KeyValuePair <string, Type> param in method.Parameters)
            {
                VarDeclNode arg = new VarDeclNode();
                arg.NameNode = new IdentifierNode {
                    Name = param.Key, Value = param.Key
                };
                arg.ArgumentType = param.Value;
                fDef.Signature.AddArgument(arg);
            }

            return(fDef);
        }
示例#18
0
 public virtual TAssociative VisitVarDeclNode(VarDeclNode node)
 {
     return(VisitAssociativeNode(node));
 }
 public virtual bool VisitVarDeclNode(VarDeclNode node)
 {
     return(DefaultVisit(node));
 }
示例#20
0
 public virtual TResult Visit(VarDeclNode node) => this.VisitChildren(node);
示例#21
0
        private void ApplyGrammar(List <ASTNode> nodes, int from = 0, bool allowNoSemicolon = false, params GrammarRule[] additionalPatterns)
        {
            int i = from;

            while (i < nodes.Count)
            {
                if (nodes[i] is NopNode)
                {
                    nodes.RemoveAt(i); // Remove the nopnode -> Should never pass through this method
                    continue;
                }

                if (additionalPatterns != null)
                {
                    bool skipStandard = false;
                    for (int j = 0; j < additionalPatterns.Length; j++)
                    {
                        if (additionalPatterns[j](nodes, ref i))
                        {
                            skipStandard = true;
                            break;
                        }
                    }
                    if (skipStandard)
                    {
                        i++;
                        continue;
                    }
                }

                if (nodes[i].LexicalType == LexTokenType.Keyword)
                {
                    switch (nodes[i].Content)
                    {
                    case "class":
                        this.ApplyClassGrammar(nodes, ref i);
                        break;

                    case "return":
                        this.ApplyReturnStatementGrammar(nodes, i);
                        break;

                    case "if":
                        this.ApplyIfStatementGrammar(nodes, i);
                        break;

                    case "while":
                        this.ApplyWhileStatementGrammar(nodes, i);
                        break;

                    case "for":
                        this.ApplyForStatementGrammar(nodes, i);
                        break;

                    case "do":
                        this.ApplyDoStatementGrammar(nodes, i);
                        break;

                    case "public":
                    case "private":
                    case "protected":
                    case "external":
                    case "internal":
                        nodes[i] = new AccessModifierNode(nodes[i].Content, nodes[i].Pos);
                        break;

                    case "namespace":
                        this.ApplyNamespaceGrammar(nodes, i);
                        break;

                    default:
                        throw new NotImplementedException(nodes[i].Content);
                    }
                }
                else if (TypeSequence <ASTNode, IdentifierNode, IdentifierNode, SeperatorNode> .Match(nodes, i))   // int x;

                {
                    this.ApplyModifierGrammar(nodes, ref i, out AccessModifierNode accessModifier, out HashSet <StorageModifierNode> storageModifiers);

                    nodes[i] = new VarDeclNode(nodes[i].Pos, nodes[i].ToTypeIdentifier(), nodes[i + 1].Content);
                    this.ApplyModifiers(nodes[i] as VarDeclNode, accessModifier, storageModifiers);
                    this.RemoveNode(nodes, i + 1, 2);
                }
                else if (TypeSequence <ASTNode, IdentifierNode, AssignmentNode, SeperatorNode> .Match(nodes, i) || TypeSequence <ASTNode, TypeArrayIdentifierNode, AssignmentNode, SeperatorNode> .Match(nodes, i))  // int x = <expr>; OR int[] x = <expr>;

                {
                    this.ApplyModifierGrammar(nodes, ref i, out AccessModifierNode accessModifier, out HashSet <StorageModifierNode> storageModifiers);

                    AssignmentNode assignOp    = nodes[i + 1] as AssignmentNode;
                    bool           doRecursive = true;

                    if (assignOp.Right is ScopeNode initializer)
                    {
                        if (this.ApplyInitializerGrammar(initializer, out IInitializer init))
                        {
                            assignOp.Update(LeftRight.LHS, assignOp.Left);
                            assignOp.Update(LeftRight.RHS, init as ASTNode);
                            doRecursive = false;
                        }
                    }
                    if (doRecursive)
                    {
                        this.ApplySingleNodeGrammar(assignOp.Right, true);
                    }
                    nodes[i] = new VarDeclNode(nodes[i].Pos, nodes[i].ToTypeIdentifier(), assignOp);
                    this.ApplyModifiers(nodes[i] as VarDeclNode, accessModifier, storageModifiers);
                    this.RemoveNode(nodes, i + 1, 2);
                }
                else if (TypeSequence <ASTNode, IdentifierNode, ExpressionNode, ASTNode, IdentifierNode, ScopeNode> .Match(nodes, i))
                {
                    if (nodes[i + 2].Content.CompareTo(":") == 0)
                    {
                        this.ApplyFunctionGrammar(nodes, ref i);
                    }
                }
                else if (TypeSequence <ASTNode, IExpr, ExpressionNode> .Match(nodes, i))
                {
                    ExpressionNode groupNode = nodes[i + 1] as ExpressionNode;
                    this.ApplyGrammar(groupNode.Nodes, 0, true); // apply grammar on arguments ==> should lead to a nice arg1,arg2,arg3 setup (otherwise error)
                    CallNode callNode = new CallNode(nodes[i], nodes[i].Pos)
                    {
                        Arguments = new ArgumentsNode(groupNode) // Note: This constructor will apply the grammar rule on its own
                    };
                    if (!callNode.Arguments.IsValid)
                    {
                        throw new Exception();
                    }
                    this.RemoveNode(nodes, i + 1);
                    nodes[i] = callNode;
                }
                else if (nodes[i] is IGroupedASTNode groupNode)
                {
                    this.ApplyGrammar(groupNode.Nodes);
                }
                else
                {
                    ApplySingleNodeGrammar(nodes[i]);
                }

                if (nodes[i] is IExpr && i + 1 < nodes.Count && nodes[i + 1] is SeperatorNode sepNode && sepNode.Content.CompareTo(";") == 0)
                {
                    this.RemoveNode(nodes, i + 1);
                }
示例#22
0
 public virtual void VisitVarDeclNode(VarDeclNode node)
 {
     Visit(node.NameListNode);
     Visit(node.ColonNode);
     Visit(node.TypeNode);
     Visit(node.FirstPortabilityDirectiveListNode);
     Visit(node.AbsoluteSemikeywordNode);
     Visit(node.AbsoluteAddressNode);
     Visit(node.EqualSignNode);
     Visit(node.ValueNode);
     Visit(node.SecondPortabilityDirectiveListNode);
     Visit(node.SemicolonNode);
 }
示例#23
0
        private ClassDeclNode ParseSystemType(Type type, string alias)
        {
            Validity.Assert(!SupressesImport(type), "Supressed type is being imported!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;
            Type baseType = GetBaseType(type);

            if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType))
            {
                string baseTypeName = CLRObjectMarshler.GetTypeName(baseType);

                classnode.superClass = new List <string>();
                classnode.superClass.Add(baseTypeName);
                //Make sure that base class is imported properly.
                CLRModuleType.GetInstance(baseType, Module, string.Empty);
            }

            // There is no static class in runtime. static class is simply
            // marked as sealed and abstract.
            bool isStaticClass = type.IsSealed && type.IsAbstract;

            if (!isStaticClass)
            {
                // If all methods are static, it doesn't make sense to expose
                // constructor.
                ConstructorInfo[] ctors = type.GetConstructors();
                foreach (var c in ctors)
                {
                    if (c.IsPublic && !c.IsGenericMethod && !SupressesImport(c))
                    {
                        ConstructorDefinitionNode node = ParseConstructor(c, type);
                        classnode.funclist.Add(node);

                        List <ProtoCore.Type> argTypes = GetArgumentTypes(node);
                        RegisterFunctionPointer(node.Name, c, argTypes, node.ReturnType);
                    }
                }
            }

            BindingFlags flags          = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
            bool         isDerivedClass = (classnode.superClass != null) && classnode.superClass.Count > 0;

            if (isDerivedClass)                     //has base class
            {
                flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods.
            }
            bool isDisposable = typeof(IDisposable).IsAssignableFrom(type);

            MethodInfo[] methods          = type.GetMethods(flags);
            bool         hasDisposeMethod = false;

            foreach (var m in methods)
            {
                if (SupressesImport(m))
                {
                    continue;
                }

                if (isStaticClass && m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(object))
                {
                    continue;
                }

                //Don't include overriden methods or generic methods
                if (m.IsPublic && !m.IsGenericMethod && m == m.GetBaseDefinition())
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
                else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
            }
            if (!hasDisposeMethod && !isDisposable)
            {
                AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod);
                classnode.funclist.Add(node);
            }

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (SupressesImport(f))
                {
                    continue;
                }

                //Supress if defined in super-type
                if (isDerivedClass)
                {
                    FieldInfo[] supertypeFields = baseType.GetFields();

                    if (supertypeFields.Any(superF => superF.Name == f.Name))
                    {
                        continue;
                    }
                }


                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    RegisterFunctionPointer(func.Name, f, null, func.ReturnType);
                }
            }

            PropertyInfo[] properties = type.GetProperties(flags);
            foreach (var p in properties)
            {
                AssociativeNode node = ParseProperty(p);
                if (null != node)
                {
                    classnode.varlist.Add(node);
                }
            }

            FFIClassAttributes cattrs = new FFIClassAttributes(type);

            classnode.ClassAttributes = cattrs;
            SetTypeAttributes(type, cattrs);

            return(classnode);
        }
示例#24
0
 public CGVarDeclNode(VarDeclNode _vardecl)
 {
     vardecl        = _vardecl;
     vardecl.cgnode = this;
 }
示例#25
0
 public void AddArgument(VarDeclNode arg)
 {
     Arguments.Add(arg);
 }
示例#26
0
        private void dfsTraverse(Node node)
        {
            if (node is TerminalNode)
            {
                TerminalNode t = node as TerminalNode;
                emit("push " + t.Value + ";\n");

                FusionCore.DSASM.Operand op = buildOperand(t);
                emitPush(op);
            }
            else if (node is FunctionDefinitionNode)
            {
                FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;

                // TODO jun: Add semantics for checking overloads (different parameter types)
                FusionCore.DSASM.FunctionNode fnode = new FusionCore.DSASM.FunctionNode();
                fnode.name       = funcDef.Name;
                fnode.paramCount = null == funcDef.Signature ? 0 : funcDef.Signature.Arguments.Count;
                fnode.pc         = pc;
                fnode.localCount = funcDef.localVars;
                fnode.returntype = FusionCore.TypeSystem.getType(funcDef.ReturnType.Name);
                functionindex    = functions.Append(fnode);

                // Append arg symbols
                if (fnode.paramCount > 0)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        AllocateArg(argNode.NameNode.Value, functionindex, FusionCore.TypeSystem.getType(argNode.ArgumentType.Name));
                    }
                }

                // Traverse definition
                foreach (Node bnode in funcDef.FunctionBody.Body)
                {
                    dfsTraverse(bnode);
                }

                // Append to the function group functiontable
                FusionCore.FunctionGroup funcGroup = new FusionCore.FunctionGroup();

                // ArgList
                if (fnode.paramCount > 0)
                {
                    List <FusionCore.Type> parameterTypes = new List <FusionCore.Type>();
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        parameterTypes.Add(FusionCore.TypeSystem.buildTypeObject(FusionCore.TypeSystem.getType(argNode.ArgumentType.Name), false));
                    }
                }

                // function return
                emit("ret" + FusionCore.DSASM.Constants.termline);
                emitReturn();
                functionindex = (int)FusionCore.DSASM.Constants.kGlobalScope;
                argOffset     = 0;
                baseOffset    = 0;
            }
            else if (node is FunctionCallNode)
            {
                FunctionCallNode funcCall           = node as FunctionCallNode;
                FusionCore.DSASM.FunctionNode fnode = new FusionCore.DSASM.FunctionNode();
                fnode.name       = funcCall.Function.Name;
                fnode.paramCount = funcCall.FormalArguments.Count;

                // Traverse the function args
                foreach (Node paramNode in funcCall.FormalArguments)
                {
                    dfsTraverse(paramNode);
                }

                int fIndex = functions.getIndex(fnode);
                if ((int)FusionCore.DSASM.Constants.kInvalidIndex != fIndex)
                {
                    emit("call " + fnode.name + FusionCore.DSASM.Constants.termline);
                    emitCall(fIndex);

                    if (FusionCore.PrimitiveType.kTypeVoid != functions.functionList[fIndex].returntype)
                    {
                        emit("push " + FusionCore.DSASM.kw.regRX + FusionCore.DSASM.Constants.termline);
                        FusionCore.DSASM.Operand opRes;
                        opRes.optype = FusionCore.DSASM.AddressType.Register;
                        opRes.opdata = (int)FusionCore.DSASM.Registers.RX;
                        emitPush(opRes);
                    }
                }
                else
                {
                    System.Console.WriteLine("Method '" + fnode.name + "' not found\n");
                }
            }
            else if (node is IfStmtNode)
            {
/*
 *
 *
 *              def backpatch(bp, pc)
 *                      instr = instrstream[bp]
 *                      if instr.opcode is jmp
 *                              instr.op1 = pc
 *                      elseif instr.opcode is cjmp
 *                              instr.op2 = pc
 *                      end
 *              end
 *
 *              def backpatch(table, pc)
 *                      foreach node in table
 *                              backpatch(node.pc, pc)
 *                      end
 *              end
 *
 */
                /*
                 * if(E)		->	traverse E
                 *                              bpTable = new instance
                 *                              L1 = pc + 1
                 *                              L2 = null
                 *              bp = pc
                 *                              emit(jmp, _cx, L1, L2)
                 * {
                 *  S		->	traverse S
                 *              L1 = null
                 *                          bpTable.append(pc)
                 *                          emit(jmp,labelEnd)
                 *                          backpatch(bp,pc)
                 * }
                 * */

                // TODO jun: Try to break up this emitter without while retaining theoretical meaning
                int bp = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                int L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                FusionCore.DSASM.Operand opCX;


                // If-expr
                IfStmtNode ifnode = node as IfStmtNode;
                dfsTraverse(ifnode.IfExprNode);

                emit("pop " + FusionCore.DSASM.kw.regCX + FusionCore.DSASM.Constants.termline);
                opCX.optype = FusionCore.DSASM.AddressType.Register;
                opCX.opdata = (int)FusionCore.DSASM.Registers.CX;
                emitPop(opCX);

                L1 = pc + 1;
                L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                emitCJmp(L1, L2);

                // If-body
                foreach (Node ifBody in ifnode.IfBody)
                {
                    dfsTraverse(ifBody);
                }

                L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                backpatchTable.append(pc, L1);
                emitJmp(L1);
                backpatch(bp, pc);


                /*
                 * else if(E)	->	traverse E
                 *              L1 = pc + 1
                 *                              L2 = null
                 *              bp = pc
                 *                              emit(jmp, _cx, L1, L2)
                 * {
                 *  S		->	traverse S
                 *              L1 = null
                 *              bpTable.append(pc)
                 *                          emit(jmp,labelEnd)
                 *                          backpatch(bp,pc)
                 * }
                 * */

                // Elseif-expr
                foreach (ElseIfBlock elseifNode in ifnode.ElseIfList)
                {
                    dfsTraverse(elseifNode.Expr);

                    emit("pop " + FusionCore.DSASM.kw.regCX + FusionCore.DSASM.Constants.termline);
                    opCX.optype = FusionCore.DSASM.AddressType.Register;
                    opCX.opdata = (int)FusionCore.DSASM.Registers.CX;
                    emitPop(opCX);

                    L1 = pc + 1;
                    L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                    bp = pc;
                    emitCJmp(L1, L2);

                    // Elseif-body
                    if (null != elseifNode.Body)
                    {
                        foreach (Node elseifBody in elseifNode.Body)
                        {
                            dfsTraverse(elseifBody);
                        }
                    }

                    L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.append(pc, L1);
                    emitJmp(L1);
                    backpatch(bp, pc);
                }

                /*
                 * else
                 * {
                 *  S		->	traverse S
                 *              L1 = null
                 *              bpTable.append(pc)
                 *                          emit(jmp,labelEnd)
                 *                          backpatch(bp,pc)
                 * }
                 * */
                // Else-body
                if (null != ifnode.ElseBody)
                {
                    foreach (Node elseBody in ifnode.ElseBody)
                    {
                        dfsTraverse(elseBody);
                    }

                    L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.append(pc, L1);
                    emitJmp(L1);
                    //backpatch(bp, pc);
                }

                /*
                 *
                 *                    ->	backpatch(bpTable, pc)
                 */
                // ifstmt-exit
                backpatch(backpatchTable.backpatchList, pc);
            }
            else if (node is VarDeclNode)
            {
                VarDeclNode varNode = node as VarDeclNode;
                Allocate(varNode.NameNode.Value, functionindex, FusionCore.TypeSystem.getType(varNode.ArgumentType.Name));
            }
            else if (node is BinaryExpressionNode)
            {
                BinaryExpressionNode b = node as BinaryExpressionNode;
                if (Operator.assign != b.Operator)
                {
                    dfsTraverse(b.LeftNode);
                }
                dfsTraverse(b.RightNode);

                if (Operator.assign == b.Operator)
                {
                    if (b.LeftNode is TerminalNode)
                    {
                        TerminalNode t = b.LeftNode as TerminalNode;

                        bool   isReturn = false;
                        string s        = t.Value;
                        if (s == "return")
                        {
                            s = "_rx";
                            //isReturn = true;
                        }

                        // TODO jun: the emit string are only for console logging,
                        // wrap them together with the actual emit function and flag them out as needed
                        emit("pop " + s + FusionCore.DSASM.Constants.termline);

                        FusionCore.DSASM.Operand op = buildOperand(t);
                        emitPop(op);

                        //if (isReturn)
                        //{
                        //    emit("ret" + FusionCore.DSASM.Constants.termline);
                        //    emitReturn();
                        //    functionindex = (int)FusionCore.DSASM.Constants.kGlobalScope;
                        //}
                    }
                }
                else
                {
                    emit("pop " + FusionCore.DSASM.kw.regBX + FusionCore.DSASM.Constants.termline);
                    FusionCore.DSASM.Operand opBX;
                    opBX.optype = FusionCore.DSASM.AddressType.Register;
                    opBX.opdata = (int)FusionCore.DSASM.Registers.BX;
                    emitPop(opBX);


                    emit("pop " + FusionCore.DSASM.kw.regAX + FusionCore.DSASM.Constants.termline);
                    FusionCore.DSASM.Operand opAX;
                    opAX.optype = FusionCore.DSASM.AddressType.Register;
                    opAX.opdata = (int)FusionCore.DSASM.Registers.AX;
                    emitPop(opAX);


                    string op = getOperator(b.Operator);
                    emit(op + " " + FusionCore.DSASM.kw.regAX + ", " + FusionCore.DSASM.kw.regBX + FusionCore.DSASM.Constants.termline);
                    emitBinary(getOpCode(b.Operator), opAX, opBX);


                    emit("push " + FusionCore.DSASM.kw.regAX + FusionCore.DSASM.Constants.termline);
                    FusionCore.DSASM.Operand opRes;
                    opRes.optype = FusionCore.DSASM.AddressType.Register;
                    opRes.opdata = (int)FusionCore.DSASM.Registers.AX;
                    emitPush(opRes);
                }
            }
        }
        private ClassDeclNode ParseSystemType(Type type, string alias)
        {
            Validity.Assert(IsBrowsable(type), "Non browsable type is being imported!!");

            string classname = alias;

            if (classname == null | classname == string.Empty)
            {
                classname = CLRObjectMarshler.GetTypeName(type);
            }

            ProtoCore.AST.AssociativeAST.ClassDeclNode classnode = CreateEmptyClassNode(classname);
            classnode.ExternLibName = Module.Name;
            classnode.className     = classname;
            classnode.Name          = type.Name;
            Type baseType = GetBaseType(type);

            if (baseType != null && !CLRObjectMarshler.IsMarshaledAsNativeType(baseType))
            {
                string baseTypeName = CLRObjectMarshler.GetTypeName(baseType);

                classnode.superClass = new List <string>();
                classnode.superClass.Add(baseTypeName);
                //Make sure that base class is imported properly.
                CLRModuleType.GetInstance(baseType, Module, string.Empty);
            }

            ConstructorInfo[] ctors = type.GetConstructors();
            foreach (var c in ctors)
            {
                if (c.IsPublic && !c.IsGenericMethod && IsBrowsable(c))
                {
                    ConstructorDefinitionNode node = ParseConstructor(c, type);
                    classnode.funclist.Add(node);
                    RegisterFunctionPointer(node.Name, c, node.ReturnType);
                }
            }

            BindingFlags flags          = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
            bool         isDerivedClass = classnode.superClass != null;

            if (isDerivedClass)                     //has base class
            {
                flags |= BindingFlags.DeclaredOnly; //for derived class, parse only class declared methods.
            }
            bool isDisposable = typeof(IDisposable).IsAssignableFrom(type);

            MethodInfo[] methods          = type.GetMethods(flags);
            bool         hasDisposeMethod = false;

            foreach (var m in methods)
            {
                if (!IsBrowsable(m))
                {
                    continue;
                }

                //Don't include overriden methods or generic methods
                if (m.IsPublic && !m.IsGenericMethod && (m == m.GetBaseDefinition() || (m.GetBaseDefinition().DeclaringType == baseType && baseType == typeof(Object))))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
                else if (!hasDisposeMethod && isDisposable && baseType == typeof(Object) && isDisposeMethod(m))
                {
                    AssociativeNode node = ParseAndRegisterFunctionPointer(isDisposable, ref hasDisposeMethod, m);
                    classnode.funclist.Add(node);
                }
            }
            if (!hasDisposeMethod && !isDisposable)
            {
                AssociativeNode node = ParseAndRegisterFunctionPointer(true, ref hasDisposeMethod, mDisposeMethod);
                classnode.funclist.Add(node);
            }

            FieldInfo[] fields = type.GetFields();
            foreach (var f in fields)
            {
                if (!IsBrowsable(f))
                {
                    continue;
                }

                VarDeclNode variable = ParseFieldDeclaration(f);
                if (null == variable)
                {
                    continue;
                }
                classnode.varlist.Add(variable);
                FunctionDefinitionNode func = ParseFieldAccessor(f);
                if (null != func)
                {
                    RegisterFunctionPointer(func.Name, f, func.ReturnType);
                }
            }

            PropertyInfo[] properties = type.GetProperties(flags);
            foreach (var p in properties)
            {
                AssociativeNode node = ParseProperty(p);
                if (null != node)
                {
                    classnode.varlist.Add(node);
                }
            }

            return(classnode);
        }
示例#28
0
 public virtual void VisitVarDeclNode(VarDeclNode node)
 {
     DefaultVisit(node);
 }
 public DeclaredVariableSymbol(string name, DeclSpecsNode specs, VarDeclNode decl, ExprNode?init = null)
     : base(name, specs, decl)
 {
     this.VariableDeclarator = decl;
     if (init is { })