コード例 #1
0
        public bool EnterInvocationExpr(InvocationExpressionSyntax invocationExpr, WaddleContext ctx)
        {
            if (_functions.ContainsKey(invocationExpr.Identifier) == false)
            {
                throw new SemanticErrorException($"function {invocationExpr.Identifier} is not defined");
            }

            FunctionDecl functionDecl = _functions[invocationExpr.Identifier] !;
            var          parameters   = functionDecl.Parameters;
            var          arguments    = invocationExpr.Arguments.ToArray();

            if (parameters.Count != arguments.Length)
            {
                throw new SemanticErrorException($"function {invocationExpr.Identifier} has {functionDecl.Parameters.Count} parameters, {invocationExpr.Arguments.Count()} arguments where given.");
            }

            // check that for all parameters: IsAssignableFrom(param.Type, arg.Type)
            for (int i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];
                var exprType  = arguments[i].Accept(TypeVisitor);
                if (parameter.Type != exprType)
                {
                    throw new SemanticErrorException($"Parameter {parameter} requires type {parameter.Type}, but type {exprType} was given.");
                }
            }

            return(true);
        }
コード例 #2
0
        public bool EnterIdentifierLiteral(IdentifierAtom atom, WaddleContext ctx)
        {
            var _ = _currentFunction?.Variables[atom.Identifier].Type
                    ?? throw new SemanticErrorException($"{atom.Identifier} does not have a type");

            return(true);
        }
コード例 #3
0
        public bool EnterPrintStmt(PrintStmtSyntax syntax, WaddleContext ctx)
        {
            foreach (var printStmtArgument in syntax.Arguments)
            {
                var exprType = printStmtArgument.Accept(TypeVisitor);
                if (exprType == TypeSymbol.Void)
                {
                    throw new SemanticErrorException("Can not print void-value.");
                }
            }

            return(true);
        }
コード例 #4
0
        public bool EnterLogicalExpr(LogicalExpressionSyntax logicalExpr, WaddleContext ctx)
        {
            if (logicalExpr.Left.Accept(TypeVisitor) != TypeSymbol.Bool)
            {
                throw new SemanticErrorException($"Not an Bool @({logicalExpr.Left.StartToken.LineNumber}{logicalExpr.Left.StartToken.CharPosition}).");
            }
            if (logicalExpr.Right.Accept(TypeVisitor) != TypeSymbol.Bool)
            {
                throw new SemanticErrorException($"Not an Bool @({logicalExpr.Right.StartToken.LineNumber}{logicalExpr.Right.StartToken.CharPosition}).");
            }

            return(true);
        }
コード例 #5
0
        public bool EnterRelationalExpr(RelationalExpressionSyntax relationalExpr, WaddleContext ctx)
        {
            if (relationalExpr.Left.Accept(TypeVisitor) != TypeSymbol.Integer)
            {
                throw new SemanticErrorException($"Not an Integer @({relationalExpr.Left.StartToken.LineNumber}{relationalExpr.Left.StartToken.CharPosition}).");
            }
            if (relationalExpr.Right.Accept(TypeVisitor) != TypeSymbol.Integer)
            {
                throw new SemanticErrorException($"Not an Integer @({relationalExpr.Right.StartToken.LineNumber}{relationalExpr.Right.StartToken.CharPosition}).");
            }

            return(true);
        }
コード例 #6
0
        public void LeaveBlock(BlockSyntax block, WaddleContext ctx)
        {
            var currentParent = ctx.Parent as FunctionDeclSyntax;

            if (currentParent != null)
            {
                if (currentParent.Name == _currentFunction !.Name && _currentFunction.Type != null)
                {
                    StatementSyntax?lastStmnt = block.Statements.LastOrDefault();
                    if (lastStmnt is ReturnStmtSyntax == false)
                    {
                        throw new SemanticErrorException("Last Statement must be return if function has a type");
                    }
                }
            }
        }
コード例 #7
0
        public bool EnterIfStmt(IfStmtSyntax ifStmt, WaddleContext ctx)
        {
            if (_currentFunction == null)
            {
                throw new SemanticErrorException($"can not use if statement outside of function.");
            }

            // check that expr is boolean
            var exprType = ifStmt.Expression.Accept(TypeVisitor);

            if (TypeSymbol.Bool != exprType)
            {
                throw new SemanticErrorException("If-Statement expression must result in boolean value.");
            }

            return(true);
        }
コード例 #8
0
        public bool EnterProgram(ProgramSyntax syntax, WaddleContext ctx)
        {
            var hasEntryPoint = false;

            foreach (var function in syntax.FunctionDeclarations)
            {
                if (function.Name == Naming.EntryPointFunctionName)
                {
                    ValidateEntryPointFunction(_functions[function.Name]);
                    hasEntryPoint = true;
                }
            }

            if (hasEntryPoint == false)
            {
                throw new SemanticErrorException("Program has no entry Point.");
            }

            return(true);
        }
コード例 #9
0
        public bool EnterDeclStmt(DeclStmtSyntax declStmt, WaddleContext ctx)
        {
            if (_currentFunction == null)
            {
                throw new SemanticErrorException($"can not use declare statement outside of function.");
            }

            if (_currentFunction?.Variables.ContainsKey(declStmt.ParameterDeclSyntax.Name) == false)
            {
                throw new SemanticErrorException($"{declStmt.ParameterDeclSyntax.Name} is not an available variable at this position.");
            }

            var variable = _currentFunction?.Variables[declStmt.ParameterDeclSyntax.Name] !;
            var exprType = declStmt.Expression.Accept(TypeVisitor);

            if (variable.Type != exprType)
            {
                throw new SemanticErrorException($"type {variable.Type} is not assignable from {exprType}.");
            }

            return(true);
        }
コード例 #10
0
        public bool EnterAssignStmt(AssignStmtSyntax assignStmt, WaddleContext ctx)
        {
            if (_currentFunction == null)
            {
                throw new SemanticErrorException($"can not use assign statement outside of function.");
            }

            if (_currentFunction !.Variables.ContainsKey(assignStmt.StartToken.Lexeme) == false)
            {
                throw new SemanticErrorException(
                          $"unknown identifier ({assignStmt.StartToken.Lexeme}) @({assignStmt.StartToken.LineNumber}{assignStmt.StartToken.CharPosition}).");
            }

            var identifier = _currentFunction?.Variables[assignStmt.StartToken.Lexeme] !;
            var exprType   = assignStmt.Expression.Accept(TypeVisitor);

            // check IsAssignableFrom
            if (identifier.Type != exprType)
            {
                throw new SemanticErrorException($"The type {exprType} can not be assigned into {identifier.Name}.");
            }

            return(true);
        }
コード例 #11
0
        public bool EnterReturnStmt(ReturnStmtSyntax returnStmt, WaddleContext ctx)
        {
            if (_currentFunction == null)
            {
                throw new SemanticErrorException($"can not use return statement outside of function.");
            }

            if (_currentFunction.Type == null)
            {
                //Ignore Type if function is typeless
                return(true);
            }

            // check IsAssignableFrom (function.type, expr.type)
            var exprType = returnStmt.Expression.Accept(TypeVisitor);

            if (_currentFunction.Type != exprType)
            {
                throw new SemanticErrorException(
                          $"Function result is of type {_currentFunction.Type!}, the type {exprType} can not be assigned as result.");
            }

            return(true);
        }
コード例 #12
0
 public bool EnterBlock(BlockSyntax block, WaddleContext ctx)
 {
     return(true);
 }
コード例 #13
0
 public void LeaveDeclStmt(DeclStmtSyntax declStmt, WaddleContext ctx)
 {
 }
コード例 #14
0
 public void LeaveAssignStmt(AssignStmtSyntax assignStmt, WaddleContext ctx)
 {
 }
コード例 #15
0
 public void LeaveReturnStmt(ReturnStmtSyntax returnStmt, WaddleContext ctx)
 {
 }
コード例 #16
0
 public void LeaveTermExpr(TermExpressionSyntax termExpr, WaddleContext ctx)
 {
 }
コード例 #17
0
 public void LeaveIntegerLiteral(IntegerLiteralAtom atom, WaddleContext ctx)
 {
 }
コード例 #18
0
 public void LeaveFunctionDeclaration(FunctionDeclSyntax syntax, WaddleContext ctx)
 {
 }
コード例 #19
0
 public void LeaveProgram(ProgramSyntax syntax, WaddleContext ctx)
 {
 }
コード例 #20
0
 public void LeaveBoolLiteral(BoolLiteralAtom atom, WaddleContext ctx)
 {
 }
コード例 #21
0
 public void LeaveLogicalExpr(LogicalExpressionSyntax logicalExpr, WaddleContext ctx)
 {
 }
コード例 #22
0
 public void LeaveStringLiteral(StringLiteralAtom atom, WaddleContext ctx)
 {
 }
コード例 #23
0
 public void LeaveRelationalExpr(RelationalExpressionSyntax relationalExpr, WaddleContext ctx)
 {
 }
コード例 #24
0
 public bool EnterStringLiteral(StringLiteralAtom atom, WaddleContext ctx)
 {
     return(true);
 }
コード例 #25
0
 public void LeaveInvocationExpr(InvocationExpressionSyntax invocationExpr, WaddleContext ctx)
 {
 }
コード例 #26
0
 public void LeaveProductExpr(ProductExpressionSyntax productExpr, WaddleContext ctx)
 {
 }
コード例 #27
0
 public bool EnterFunctionDeclaration(FunctionDeclSyntax syntax, WaddleContext ctx)
 {
     _currentFunction = _currentFunction = _functions[syntax.Name];
     return(true);
 }
コード例 #28
0
 public bool EnterBoolLiteral(BoolLiteralAtom atom, WaddleContext ctx)
 {
     return(true);
 }
コード例 #29
0
 public void LeaveIfStmt(IfStmtSyntax ifStmt, WaddleContext ctx)
 {
 }
コード例 #30
0
 public bool EnterIntegerLiteral(IntegerLiteralAtom atom, WaddleContext ctx)
 {
     return(true);
 }