예제 #1
0
        public object Visit(VarDeclarationStmt stmt)
        {
            // If not null or empty
            if (stmt.ArraySizes != null && stmt.ArraySizes.Count > 0)
            {
                // Make sure each size specifier is of type int.
                foreach (var size in stmt.ArraySizes)
                {
                    if (!size.Accept(this).BaseType.IsInt())
                    {
                        Reporter.Error(new Pos(0, 0), "Array size specifier should be of type 'int'.");
                    }
                }
            }

            // If assignment is present
            if (stmt.Value != null)
            {
                DataType type1 = stmt.DataType;
                DataType type2 = stmt.Value.Accept(this);

                // Make sure the assignment value is compatible with the variable type.
                DataType finalType = ApplyCastingRuleIfNeeded(stmt.Identifier.Position, type2, type1, stmt.Value);
                //_types[stmt.Identifier.Lexeme] =
                _scope.Define(stmt.Identifier.Lexeme, finalType, false);
            }
            else
            {
                //_types[stmt.Identifier.Lexeme] =
                _scope.Define(stmt.Identifier.Lexeme, stmt.DataType, false);
            }

            return(null);
        }
예제 #2
0
        public void TestMultipleIdentifiersVariableDeclaration()
        {
            var programSource = new TokenList()
            {
                { TokenType.KwVar },
                { TokenType.Identifier, "asd" },
                { TokenType.Comma },
                { TokenType.Identifier, "lol" },
                { TokenType.Comma },
                { TokenType.Identifier, "foo" },
                { TokenType.Colon },
                { TokenType.Identifier, "bool" }
            };
            Parser      parser  = new Parser(CreateMockScanner(programSource), new ErrorHandler());
            ProgramNode program = parser.Parse();

            var declr = new VarDeclarationStmt(0, 0);

            declr.Identifiers.Add("asd");
            declr.Identifiers.Add("lol");
            declr.Identifiers.Add("foo");
            declr.Type = new SimpleType(0, 0, ExprType.Bool);
            expected.Block.Statements.Add(declr);
            program.ShouldBeEquivalentTo(expected);
        }
예제 #3
0
        public void TestArrayDeclaration()
        {
            var programSource = new TokenList()
            {
                { TokenType.KwVar },
                { TokenType.Identifier, "asd" },
                { TokenType.Colon },
                { TokenType.KwArray },
                { TokenType.LBracket },
                { TokenType.IntLiteral, "3" },
                { TokenType.RBracket },
                { TokenType.KwOf },
                { TokenType.Identifier, "int" }
            };
            Parser      parser  = new Parser(CreateMockScanner(programSource), new ErrorHandler());
            ProgramNode program = parser.Parse();

            var declr = new VarDeclarationStmt(0, 0);

            declr.Identifiers.Add("asd");
            var type = new ArrayType(0, 0, ExprType.Int);

            type.SizeExpr = new IntLiteralExpr(0, 0, 3);
            declr.Type    = type;
            expected.Block.Statements.Add(declr);
            program.ShouldBeEquivalentTo(expected);
        }
예제 #4
0
        public object Visit(VarDeclarationStmt stmt)
        {
            LLVMTypeRef  type = stmt.DataType.BaseType.ToLLVMType();
            LLVMValueRef alloca;

            // If not null or empty, meaning it is an array
            if (stmt.ArraySizes != null && stmt.ArraySizes.Count > 0)
            {
                // Generate code for each size expression
                LLVMValueRef[] sizeValueRefs = new LLVMValueRef[stmt.ArraySizes.Count];
                for (int k = 0; k < sizeValueRefs.Length; k++)
                {
                    sizeValueRefs[k] = stmt.ArraySizes[k].Accept(this);
                }

                LLVMValueRef size = sizeValueRefs[0];
                for (int i = 1; i < stmt.ArraySizes.Count; i++)
                {
                    size = LLVM.BuildMul(_builder, size, sizeValueRefs[i], "multmp");
                }

                // Allocate some extra space to specify the array length(s).
                size = LLVM.BuildAdd(_builder, size,
                                     LLVM.ConstInt(LLVM.Int32Type(), (ulong)stmt.ArraySizes.Count,
                                                   LLVMBoolFalse), "addtmp");
                alloca = LLVM.BuildArrayAlloca(_builder, type, size, stmt.Identifier.Lexeme);

                // Store array length(s) at the start of the array.
                for (int j = 0; j < sizeValueRefs.Length; j++)
                {
                    var indices = new LLVMValueRef[]
                    {
                        LLVM.ConstInt(LLVM.Int32Type(), (ulong)j, LLVMBoolFalse)
                    };
                    LLVMValueRef gep = LLVM.BuildGEP(_builder, alloca, indices, "geptmp");
                    LLVM.BuildStore(_builder, sizeValueRefs[j], gep);
                }
            }
            else
            {
                alloca = LLVM.BuildAlloca(_builder, type, stmt.Identifier.Lexeme); // Allocate variable
            }

            var namedValue = stmt.ArraySizes == null
                             ? new NamedValue(alloca, 0)
                             : new NamedValue(alloca, stmt.ArraySizes.Count);

            _namedValues.Add(stmt.Identifier.Lexeme, namedValue); // Add to dictionary

            if (stmt.Value != null)
            {
                LLVMValueRef initializer = stmt.Value.Accept(this);
                LLVM.BuildStore(_builder, initializer, alloca);
            }

            return(null);
        }
        private static VarDeclarationStmt CreateVarDeclaration(string name, TypeNode type = null)
        {
            if (type == null)
            {
                type = new SimpleType(0, 0, ExprType.Int);
            }
            var declaration = new VarDeclarationStmt(0, 0);

            declaration.Identifiers.Add(name);
            declaration.Type = type;
            return(declaration);
        }
예제 #6
0
        public override void Visit(VarDeclarationStmt stmt)
        {
            if (stmt.initializer != null)
            {
                stmt.initializer.Accept(this);
            }
            else
            {
                chunk.WriteOpCode(OpCode.NIL);
            }
            ushort addr = chunk.AddConstant(new Value(stmt.name.lexeme));

            chunk.WriteOpCode(OpCode.DEF_GLOBAL);
            chunk.WriteWord(addr);
        }
예제 #7
0
 public override void Visit(VarDeclarationStmt stmt)
 {
     if (isNewLine)
     {
         isNewLine = false;
         AddStr(WS());
     }
     AddStr("var " + stmt.name.lexeme);
     if (stmt.initializer != null)
     {
         AddStr(" = ");
         stmt.initializer.Accept(this);
         AddStr(";");
         NewLine();
     }
 }
예제 #8
0
 public virtual void Visit(VarDeclarationStmt stmt)
 {
 }