public override void Visit(AssignmentStmt assignmentStmt)
 {
     IdentifierExpr id = assignmentStmt.Identifier;
     id.Accept(this);
     Expression assignment = assignmentStmt.AssignmentExpr;
     assignment.Accept(this);
     if (assignment.Type == ExprType.VoidType)
         return;
     if (id.Type != assignment.Type)
     {
         Errors.AddError(String.Format("Can't assign expression of type {0} in variable {1} of type {2} at line {3} column {4}.",
             assignment.Type, id.IdentifierName, id.Type, assignmentStmt.Line, assignmentStmt.Column), ErrorTypes.SemanticError);
     }
 }
        public void TestAssignArrayInArray()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration1 = CreateVarDeclaration("var1");
            var declaration2 = CreateVarDeclaration("var2");
            var assign       = new AssignmentStmt(0, 0);

            assign.Variable       = new VariableExpr(0, 0, "var1");
            assign.AssignmentExpr = new VariableExpr(0, 0, "var2");
            program.Block.Statements.Add(declaration1);
            program.Block.Statements.Add(declaration2);
            program.Block.Statements.Add(assign);
            AssertNoErrors(program);
        }
        public void TestAssignToVariableDeclaredInOuterScope()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1");
            var assign      = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = new IntLiteralExpr(0, 0, 1);
            assign.Variable       = new VariableExpr(0, 0, "var1");
            var innerBlock = new BlockStmt(0, 0);

            innerBlock.Statements.Add(assign);
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(innerBlock);
            AssertNoErrors(program);
        }
        public void TestAssignInArrayElement()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new ArrayType(0, 0, ExprType.Int));
            var assign      = new AssignmentStmt(0, 0);
            var array       = new ArrayVariableExpr(0, 0);

            array.ArrayIdentifier = "var1";
            array.SubscriptExpr   = new IntLiteralExpr(0, 0, 1);
            assign.Variable       = array;
            assign.AssignmentExpr = new IntLiteralExpr(0, 0, 1);
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertNoErrors(program);
        }
        public void TestCallUndeclaredFunctionInExpression()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var assign = new AssignmentStmt(0, 0);

            assign.Variable = new VariableExpr(0, 0, "var1");
            var call = new CallExpr(0, 0);

            call.Arguments.Add(new IntLiteralExpr(0, 0, 1));
            call.CalleeId         = "func";
            assign.AssignmentExpr = call;
            program.Block.Statements.Add(CreateVarDeclaration("var1"));
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Undeclared function 'func'");
        }
        public void TestCallProcedureInExpression()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var assign = new AssignmentStmt(0, 0);

            assign.Variable = new VariableExpr(0, 0, "var1");
            var call = new CallExpr(0, 0);

            call.Arguments.Add(new IntLiteralExpr(0, 0, 1));
            call.CalleeId         = "proc";
            assign.AssignmentExpr = call;
            program.Block.Statements.Add(CreateProcedure("proc"));
            program.Block.Statements.Add(CreateVarDeclaration("var1"));
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "'proc' is not defined as a function");
        }
        public void TestAccessSizeOfNotArray()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new ArrayType(0, 0, ExprType.Int));
            var assign      = new AssignmentStmt(0, 0);

            assign.Variable = new VariableExpr(0, 0, "var1");
            var access = new MemberAccessExpr(0, 0);

            access.AccessedExpr   = new IntLiteralExpr(0, 0, 1);
            access.MemberId       = "size";
            assign.AssignmentExpr = access;
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Int has no member 'size'");
        }
Ejemplo n.º 8
0
        public IType Infer(IScope _, AssignmentStmt node)
        {
            var   scope = node.NearestScope();
            IType expType;
            var   varType = Infer(scope, node.VariableRef);

            if (node.Expression != null)
            {
                expType = Infer(node.Expression);
                if (expType.TypeId != varType.TypeId)
                {
                    TypeMismatch(node, varType, expType);
                }
            }

            TypeInferred(node, varType);
            return(varType);
        }
        public void TestArrayAccessOnNotArray()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1");
            var assign      = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = new IntLiteralExpr(0, 0, 1);
            var arrayAccess = new ArrayVariableExpr(0, 0);

            arrayAccess.ArrayIdentifier = "var1";
            arrayAccess.SubscriptExpr   = new IntLiteralExpr(0, 0, 1);
            assign.Variable             = arrayAccess;
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Variable 'var1' is not declared as an array");
        }
        public void TestArraySubscriptionWithWrongType()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new ArrayType(0, 0, ExprType.Int));
            var assign      = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = new IntLiteralExpr(0, 0, 1);
            var arrayAccess = new ArrayVariableExpr(0, 0);

            arrayAccess.ArrayIdentifier = "var1";
            arrayAccess.SubscriptExpr   = new StringLiteralExpr(0, 0, "asd");
            assign.Variable             = arrayAccess;
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Array subscript expression has to be of type Int");
        }
        public void TestCorrectUnaryExpression()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new SimpleType(0, 0, ExprType.Bool));
            var expr        = new UnaryExpr(0, 0);

            expr.Expr = new VariableExpr(0, 0, "true");
            expr.Op   = Operator.Not;
            var assign = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = expr;
            assign.Variable       = new VariableExpr(0, 0, "var1");
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertNoErrors(program);
        }
        public void TestIncorrectUnaryExpression()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new SimpleType(0, 0, ExprType.Bool));
            var expr        = new UnaryExpr(0, 0);

            expr.Expr = new IntLiteralExpr(0, 0, 1);
            expr.Op   = Operator.Not;
            var assign = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = expr;
            assign.Variable       = new VariableExpr(0, 0, "var1");
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Can't apply operator Not on type Int");
        }
Ejemplo n.º 13
0
        public void TestVariableAssigment()
        {
            var programSource = new TokenList()
            {
                { TokenType.Identifier, "var1" },
                { TokenType.OpAssignment },
                { TokenType.IntLiteral, "1" }
            };
            Parser      parser  = new Parser(CreateMockScanner(programSource), new ErrorHandler());
            ProgramNode program = parser.Parse();

            var assign = new AssignmentStmt(0, 0);

            assign.Variable       = new VariableExpr(0, 0, "var1");
            assign.AssignmentExpr = new IntLiteralExpr(0, 0, 1);
            expected.Block.Statements.Add(assign);

            program.ShouldBeEquivalentTo(expected);
        }
        public void TestAccessArraySize()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration  = CreateVarDeclaration("var1", new ArrayType(0, 0, ExprType.Int));
            var declaration2 = CreateVarDeclaration("var2");
            var assign       = new AssignmentStmt(0, 0);
            var member       = new MemberAccessExpr(0, 0);

            member.AccessedExpr   = new VariableExpr(0, 0, "var1");
            member.MemberId       = "size";
            assign.Variable       = new VariableExpr(0, 0, "var2");
            assign.AssignmentExpr = member;
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(declaration2);
            program.Block.Statements.Add(assign);
            AssertNoErrors(program);
        }
        public void TestIncorrectBinaryExpression()
        {
            var program = new ProgramNode(0, 0);

            program.Block = new BlockStmt(0, 0);
            var declaration = CreateVarDeclaration("var1", new SimpleType(0, 0, ExprType.Bool));
            var expr        = new BinaryExpr(0, 0);

            expr.Left  = new IntLiteralExpr(0, 0, 1);
            expr.Right = new RealLiteralExpr(0, 0, (float)3.4);
            expr.Op    = Operator.Modulus;
            var assign = new AssignmentStmt(0, 0);

            assign.AssignmentExpr = expr;
            assign.Variable       = new VariableExpr(0, 0, "var1");
            program.Block.Statements.Add(declaration);
            program.Block.Statements.Add(assign);
            AssertErrorContains(program, "Can't apply operator Modulus on types Real and Int");
        }
Ejemplo n.º 16
0
        public object Visit(AssignmentStmt stmt)
        {
            stmt.Identifier.DataType = _scope.Get(stmt.Identifier.Lexeme).Item1;
            DataType type1 = stmt.Identifier.DataType;
            DataType type2 = stmt.Value.Accept(this);

            if (stmt.ArrayIndexes != null)
            {
                foreach (IExpression arrIndex in stmt.ArrayIndexes)
                {
                    arrIndex.Accept(this);
                }

                type1.ArrayDepth = type1.ArrayDepth - stmt.ArrayIndexes.Count; // Adjust depth after accounting for indexing.
            }

            ApplyCastingRuleIfNeeded(stmt.Identifier.Position, type2, type1, stmt.Value);

            return(null);
        }
Ejemplo n.º 17
0
        public void TestRealLiteral()
        {
            var programSource = new TokenList()
            {
                { TokenType.Identifier, "x" },
                { TokenType.OpAssignment },
                { TokenType.RealLiteral, "2.4e3" }
            };
            Parser      parser  = new Parser(CreateMockScanner(programSource), new ErrorHandler());
            ProgramNode program = parser.Parse();

            var expr = new IntLiteralExpr(0, 0, 5);

            expr.Sign = ExprSign.Minus;
            var assignment = new AssignmentStmt(0, 0);

            assignment.Variable       = new VariableExpr(0, 0, "x");
            assignment.AssignmentExpr = new RealLiteralExpr(0, 0, 2400);
            expected.Block.Statements.Add(assignment);
            program.ShouldBeEquivalentTo(expected);
        }
Ejemplo n.º 18
0
        public void TestRelationalExpression()
        {
            // 1 + 2 < 3 * 4
            var programSource = new TokenList()
            {
                { TokenType.Identifier, "x" },
                { TokenType.OpAssignment },
                { TokenType.IntLiteral, "1" },
                { TokenType.Plus },
                { TokenType.IntLiteral, "2" },
                { TokenType.OpLess },
                { TokenType.IntLiteral, "3" },
                { TokenType.OpMultiply },
                { TokenType.IntLiteral, "4" }
            };
            Parser      parser  = new Parser(CreateMockScanner(programSource), new ErrorHandler());
            ProgramNode program = parser.Parse();

            var leftExpr = new BinaryExpr(0, 0);

            leftExpr.Left  = new IntLiteralExpr(0, 0, 1);
            leftExpr.Right = new IntLiteralExpr(0, 0, 2);
            leftExpr.Op    = Operator.Plus;
            var rightExpr = new BinaryExpr(0, 0);

            rightExpr.Left  = new IntLiteralExpr(0, 0, 3);
            rightExpr.Right = new IntLiteralExpr(0, 0, 4);
            rightExpr.Op    = Operator.Times;
            var comp = new BinaryExpr(0, 0);

            comp.Left  = leftExpr;
            comp.Right = rightExpr;
            comp.Op    = Operator.Less;
            var assignment = new AssignmentStmt(0, 0);

            assignment.AssignmentExpr = comp;
            assignment.Variable       = new VariableExpr(0, 0, "x");
            expected.Block.Statements.Add(assignment);
            program.ShouldBeEquivalentTo(expected);
        }
Ejemplo n.º 19
0
        public object Visit(AssignmentStmt stmt)
        {
            LLVMValueRef value = stmt.Value.Accept(this); // Get value after '='

            NamedValue namedValue;

            if (_namedValues.TryGetValue(stmt.Identifier.Lexeme, out namedValue)) // Get variable reference
            {
                LLVMValueRef varRef = namedValue.ValueRef;
                if (stmt.ArrayIndexes != null && stmt.ArrayIndexes.Count > 0) // If array
                {
                    varRef = GetArrayItem(varRef, namedValue.ArrayDepth, stmt.ArrayIndexes);
                }

                LLVM.BuildStore(_builder, value, varRef);
            }
            else
            {
                Reporter.Error(stmt.Identifier.Position,
                               $"Variable {stmt.Identifier.Lexeme} has not been declared.");
            }

            return(null);
        }
Ejemplo n.º 20
0
 public override void Visit(AssignmentStmt assignmentStmt)
 {
     assignmentStmt.AssignmentExpr.Accept(this);
     SymbolTable.SetSymbolValue(assignmentStmt.Identifier.IdentifierName, assignmentStmt.AssignmentExpr.ExprValue);
 }
Ejemplo n.º 21
0
        protected Statement ReadStatement()
        {
            var instruction = ReadInstruction();

            switch (instruction)
            {
            case LabelInstruction label:
                Debug.Assert(label.Name != "else" && label.Name != "}");
                if (label.Name == "{")
                {
                    return(ReadBlockStatement());
                }
                return(new JumpLabelStmt {
                    Name = label.Name.EscapeIdentifier()
                });

            case CallInstruction func:

                #region Handle assignments
                if (func.Name == "=")
                {
                    if (_currentAssignmentTarget == null)
                    {
                        throw new FormatException("No assignment target set");
                    }

                    Expression expr;
                    if (func.Arguments.Length == 0)
                    {
                        // a call to =() with no arguments means the result of the following function call is assigned
                        if (CurrentInstruction is CallInstruction callInstruction)
                        {
                            expr = new FunctionCallExpr {
                                CallStmt = new FunctionCallStmt {
                                    MethodName = callInstruction.Name, Arguments = MapToExpressions(callInstruction.Arguments)
                                }
                            };
                            _currentInstructionOffset++;
                        }
                        else
                        {
                            throw new FormatException("A parameterless call to =() must be followed by a function call, found " + CurrentInstruction);
                        }
                    }
                    else
                    {
                        // otherwise, the arguments are alternating operands and operators
                        expr = ToExpression(func.Arguments);
                    }

                    if (_currentAssignmentTarget is AssignmentTarget.Local local)
                    {
                        _locals[local.Id]        = expr;
                        _currentAssignmentTarget = null;
                        return(null);
                    }

                    var assigment = new AssignmentStmt {
                        Target = _currentAssignmentTarget, Expression = expr
                    };
                    _currentAssignmentTarget = null;
                    return(assigment);
                }
                #endregion

                var callStatement = new FunctionCallStmt {
                    MethodName = func.Name, Arguments = MapToExpressions(func.Arguments)
                };

                #region Handle body functions

                if (CurrentInstruction is LabelInstruction startLabel && startLabel.Name == "{")
                {
                    _currentInstructionOffset++;                             // skip opening brace

                    var body = ReadBlockStatement();

                    #region Handle if statements

                    if (callStatement.MethodName.ToLower() == "if")
                    {
                        if (Script.InstructionList.Count <= _currentInstructionOffset ||
                            !(Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseKeyword) ||
                            elseKeyword.Name != "else")
                        {
                            // no else block
                            return new IfStmt {
                                       Function = callStatement, Body = body
                            }
                        }
                        ;

                        BlockStmt elseBody;
                        // skip else keyword
                        _currentInstructionOffset++;
                        if (Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseStart && elseStart.Name == "{")
                        {
                            // skip opening brace
                            _currentInstructionOffset++;

                            elseBody = ReadBlockStatement();
                        }
                        else
                        {
                            // "Kimi o Aogi Otome wa Hime ni" has these bodyless else keywords in data01:system/selectjumpstart.yks
                            Console.WriteLine("Warning: Loose else keyword without body");
                            elseBody = new BlockStmt();
                            //throw new FormatException("Else keyword must be followed by an opening brace");
                        }

                        return(new IfStmt {
                            Function = callStatement, Body = body, ElseBody = elseBody
                        });
                    }

                    #endregion

                    return(new BodyFunctionStmt {
                        Function = callStatement, Body = body
                    });
                }

                #endregion

                return(callStatement);

            case TargetInstruction target:
                SetAssignmentTarget(target);
                return(null);

            default:
                throw new FormatException("Invalid statement instruction: " + instruction);
            }
        }
Ejemplo n.º 22
0
 private Statement ParseStatement()
 {
     if (Accept(Token.Types.KwVar))
     {
         DeclarationStmt declaration = new DeclarationStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token id = Match(Token.Types.Identifier);
         declaration.Identifier = new IdentifierExpr(id.Line, id.Column, id.Content);
         Match(Token.Types.Colon);
         TypeNode typeNode = ParseType();
         declaration.Type = typeNode;
         if (Accept(Token.Types.OpAssignment))
         {
             declaration.AssignmentExpr = ParseExpression();
         }
         return declaration;
     }
     else if (Accept(Token.Types.Identifier))
     {
         AssignmentStmt statement = new AssignmentStmt(AcceptedToken.Line, AcceptedToken.Column);
         statement.Identifier = new IdentifierExpr(AcceptedToken.Line, AcceptedToken.Column, AcceptedToken.Content);
         Match(Token.Types.OpAssignment);
         statement.AssignmentExpr = ParseExpression();
         return statement;
     }
     else if (Accept(Token.Types.KwFor))
     {
         ForStmt statement = new ForStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token idToken = Match(Token.Types.Identifier);
         statement.LoopVar = new IdentifierExpr(idToken.Line, idToken.Column, idToken.Content);
         Match(Token.Types.KwIn);
         statement.StartExpr = ParseExpression();
         Match(Token.Types.OpRange);
         statement.EndExpr = ParseExpression();
         Match(Token.Types.KwDo);
         statement.Body = ParseStatements(new StmtList(CurrentToken.Line, CurrentToken.Column));
         Match(Token.Types.KwEnd);
         Match(Token.Types.KwFor);
         return statement;
     }
     else if (Accept(Token.Types.KwRead))
     {
         ReadStmt statement = new ReadStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token idToken = Match(Token.Types.Identifier);
         statement.Variable = new IdentifierExpr(idToken.Line, idToken.Column, idToken.Content);
         return statement;
     }
     else if (Accept(Token.Types.KwPrint))
     {
         PrintStmt statement = new PrintStmt(AcceptedToken.Line, AcceptedToken.Column);
         statement.PrintExpr = ParseExpression();
         return statement;
     }
     else if (Accept(Token.Types.KwAssert))
     {
         AssertStmt statement = new AssertStmt(AcceptedToken.Line, AcceptedToken.Column);
         Match(Token.Types.LParen);
         statement.AssertExpr = ParseExpression();
         Match(Token.Types.RParen);
         return statement;
     }
     throw new ParserException(String.Format("Expected statement, got {0} instead at line {1} column {2}.",
         CurrentToken.Type, CurrentToken.Line, CurrentToken.Column));
 }
Ejemplo n.º 23
0
 public virtual void Visit(AssignmentStmt stmt)
 {
     stmt.Expression.Accept(this);
 }