Beispiel #1
0
        public LiteralValueNode ParseLitealValue(Token token)
        {
            if (token.Type == TokenType.LiteralValue)
            {
                LiteralValueNode value      = null;
                CobaltType       cobaltType = token.GetData <CobaltType>(TokenDataKeys.COBALT_TYPE);
                switch (cobaltType)
                {
                case CobaltType.Boolean:
                    value = new BooleanValueNode(token.SourceLine, token.GetData <bool>(TokenDataKeys.LITERAL_VALUE));
                    break;

                case CobaltType.Float:
                    value = new FloatValueNode(token.SourceLine, token.GetData <float>(TokenDataKeys.LITERAL_VALUE));
                    break;

                case CobaltType.Integer:
                    value = new IntegerValueNode(token.SourceLine, token.GetData <int>(TokenDataKeys.LITERAL_VALUE));
                    break;

                default:
                    throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with unknown Cobalt type `{cobaltType}`.");
                }
                return(value);
            }
            else
            {
                throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with a bad token. Expected a token of type `{TokenType.LiteralValue}`, got token of type `{token.Type}` instead.");
            }
        }
Beispiel #2
0
        public void ShouldParseTypeKeywords(CobaltType type)
        {
            // Arrange
            Token token = new Token(TokenType.TypeKeyword, 1, 0);

            token.SetData(TokenDataKeys.COBALT_TYPE, type);

            // Act
            TypeKeywordNode node = Parser.ParseTypeKeyword(token);

            // Assert
            switch (type)
            {
            case CobaltType.Boolean:
                Assert.True(node is BooleanTypeKeywordNode);
                break;

            case CobaltType.Float:
                Assert.True(node is FloatTypeKeywordNode);
                break;

            case CobaltType.Integer:
                Assert.True(node is IntegerTypeKeywordNode);
                break;

            default:
                throw new XunitException("No test implemented for this type.");
            }
            Assert.Equal(type, node.Type);
        }
Beispiel #3
0
        public TypeKeywordNode ParseTypeKeyword(Token token)
        {
            if (token.Type == TokenType.TypeKeyword)
            {
                TypeKeywordNode type       = null;
                CobaltType      cobaltType = token.GetData <CobaltType>(TokenDataKeys.COBALT_TYPE);
                switch (cobaltType)
                {
                case CobaltType.Boolean:
                    type = new BooleanTypeKeywordNode(token.SourceLine);
                    break;

                case CobaltType.Float:
                    type = new FloatTypeKeywordNode(token.SourceLine);
                    break;

                case CobaltType.Integer:
                    type = new IntegerTypeKeywordNode(token.SourceLine);
                    break;

                default:
                    throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with unknown Cobalt type `{cobaltType}`.");
                }
                return(type);
            }
            else
            {
                throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with a bad token. Expected a token of type `{TokenType.TypeKeyword}`, got token of type `{token.Type}` instead.");
            }
        }
Beispiel #4
0
        private void AnalyzeVariableDeclaration(VariableDeclarationStatementNode variableDeclaration)
        {
            CobaltType variableType;

            if (variableDeclaration.TypeKeyword != null && variableDeclaration.Expression != null)
            {
                CobaltType expressionType = AnalyzeExpression(variableDeclaration.Expression);
                if (expressionType != variableDeclaration.TypeKeyword.Type)
                {
                    throw new CobaltTypeError($"Type mismatch between explicitely declared type of variable `{variableDeclaration.Identifier.IdentifierName}` ({variableDeclaration.TypeKeyword.Type}) and type of expression ({expressionType}).", variableDeclaration.Expression.SourceLine);
                }
                variableType = expressionType;
            }
            else if (variableDeclaration.TypeKeyword == null && variableDeclaration.Expression != null)
            {
                variableType = AnalyzeExpression(variableDeclaration.Expression);
            }
            else if (variableDeclaration.TypeKeyword != null && variableDeclaration.Expression == null)
            {
                variableType = variableDeclaration.TypeKeyword.Type;
            }
            else
            {
                throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with bad AST stucture in variable declaration from line {variableDeclaration.SourceLine}.");
            }
            Symbol variable = new Symbol(variableDeclaration.Identifier.IdentifierName,
                                         new VariableTypeSignature(variableType),
                                         variableDeclaration.Expression != null,
                                         variableDeclaration.SourceLine);

            variableDeclaration.Parent.RegisterSymbol(variable);
        }
Beispiel #5
0
        /// <summary>
        /// Creates a token for a type keyword.
        /// </summary>
        /// <param name="type">The Cobalt type this is a keyword for.</param>
        /// <param name="line">The line in the source code where the token is from.</param>
        /// <param name="positionOnLine">The position on the source code line.</param>
        /// <returns>Returns the newly created token.</returns>
        private Token CreateTypeKeywordToken(CobaltType type, int line, int positionOnLine)
        {
            Token token = new Token(TokenType.TypeKeyword, line, positionOnLine);

            token.SetData(TokenDataKeys.COBALT_TYPE, type);
            return(token);
        }
Beispiel #6
0
        /// <summary>
        /// Creates a token for a literal value.
        /// </summary>
        /// <param name="type">The Cobalt type of the literal vbalue.</param>
        /// <param name="value">The literal value.</param>
        /// <param name="line">The line in the source code where the token is from.</param>
        /// <param name="positionOnLine">The position on the source code line.</param>
        /// <returns>Returns the newly created token.</returns>
        private Token CreateLiteralValueToken(CobaltType type, object value, int line, int positionOnLine)
        {
            Token token = new Token(TokenType.LiteralValue, line, positionOnLine);

            token.SetData(TokenDataKeys.COBALT_TYPE, type);
            token.SetData(TokenDataKeys.LITERAL_VALUE, value);
            return(token);
        }
Beispiel #7
0
        public void ShouldParseLiteralValues(object value, CobaltType type)
        {
            // Arrange
            Token token = new Token(TokenType.LiteralValue, 1, 0);

            token.SetData(TokenDataKeys.LITERAL_VALUE, value);
            token.SetData(TokenDataKeys.COBALT_TYPE, type);

            // Act
            LiteralValueNode node = Parser.ParseLitealValue(token);

            // Assert
            switch (type)
            {
            case CobaltType.Boolean:
                if (node is BooleanValueNode booleanValue)
                {
                    Assert.Equal((bool)value, booleanValue.Value);
                }
                else
                {
                    throw new XunitException("Wrong Cobalt type.");
                }
                break;

            case CobaltType.Float:
                if (node is FloatValueNode floatValue)
                {
                    Assert.Equal((float)value, floatValue.Value);
                }
                else
                {
                    throw new XunitException("Wrong Cobalt type.");
                }
                break;

            case CobaltType.Integer:
                if (node is IntegerValueNode integerValue)
                {
                    Assert.Equal((int)value, integerValue.Value);
                }
                else
                {
                    throw new XunitException("Wrong Cobalt type.");
                }
                break;

            default:
                throw new XunitException("No test implemented for this type.");
            }
        }
Beispiel #8
0
        public void ShouldParseSingleValueExpressions(object value, CobaltType type)
        {
            // Arrange
            List <Token> tokens = new List <Token>()
            {
                new Token(TokenType.LiteralValue, 1, 0)
            };

            tokens.First().SetData(TokenDataKeys.LITERAL_VALUE, value);
            tokens.First().SetData(TokenDataKeys.COBALT_TYPE, type);

            // Act
            ExpressionNode expression = Parser.ParseExpression(tokens);

            // Assert
            if (expression is SingleLeafExpressionNode singleLeafExpression)
            {
                Assert.Equal(expression, singleLeafExpression.Leaf.Parent);
                if (singleLeafExpression.Leaf is BooleanValueNode booleanValue)
                {
                    Assert.Equal(CobaltType.Boolean, type);
                    Assert.Equal((bool)value, booleanValue.Value);
                }
                else if (singleLeafExpression.Leaf is FloatValueNode floatValue)
                {
                    Assert.Equal(CobaltType.Float, type);
                    Assert.Equal((float)value, floatValue.Value);
                }
                else if (singleLeafExpression.Leaf is IntegerValueNode integerValue)
                {
                    Assert.Equal(CobaltType.Integer, type);
                    Assert.Equal((int)value, integerValue.Value);
                }
                else
                {
                    throw new XunitException("Wrong expression type.");
                }
            }
            else
            {
                throw new XunitException("Wrong expression type.");
            }
        }
Beispiel #9
0
        private void AnalyzeVariableAssignment(VariableAssignmentStatementNode variableAssignment)
        {
            Symbol     variable       = variableAssignment.Parent.LookupSymbol(variableAssignment.Identifier.IdentifierName);
            CobaltType expressionType = AnalyzeExpression(variableAssignment.Expression);

            if (variable.Type is VariableTypeSignature variableType)
            {
                if (variableType.CobaltType == expressionType)
                {
                    variable.Initialized = true;
                }
                else
                {
                    throw new CobaltTypeError($"Type mismatch between variable type of variable `{variableAssignment.Identifier.IdentifierName}` ({variableType.CobaltType}) and type of expression ({expressionType}).", variableAssignment.Expression.SourceLine);
                }
            }
            else
            {
                throw new CompilerException($"The type signature of identifier `{variable.Identifier}` is not a variable type signature.");
            }
        }
Beispiel #10
0
 public LiteralValueNode(int sourceLine, CobaltType type) : base(sourceLine)
 {
     Type = type;
 }
Beispiel #11
0
 public VariableTypeSignature(CobaltType type)
 {
     CobaltType = type;
 }
Beispiel #12
0
 public TypeKeywordNode(int sourceLine, CobaltType type) : base(sourceLine)
 {
     Type = type;
 }
Beispiel #13
0
 private bool IsNumberType(CobaltType type)
 {
     return(type == CobaltType.Integer || type == CobaltType.Float);
 }
Beispiel #14
0
        public void ShouldParseOutputStatementWithSingleValue(object value, CobaltType type)
        {
            // Arrange
            List <Token> tokens = new List <Token>()
            {
                new Token(TokenType.StandardOutput, 0, 0),
                new Token(TokenType.LiteralValue, 0, 0),
                new Token(TokenType.Semicolon, 0, 0),
            };

            tokens.ElementAt(1).SetData(TokenDataKeys.LITERAL_VALUE, value);
            tokens.ElementAt(1).SetData(TokenDataKeys.COBALT_TYPE, type);

            // Act
            CobaltProgram program = Parser.Parse(tokens);

            // Assert
            Assert.Single(program.Code.Statements);

            StatementNode statement = program.Code.Statements.First();

            if (statement is StandardOutputStatementNode outputStatement)
            {
                Assert.Equal(program.Code, outputStatement.Parent);
                ExpressionNode expression = outputStatement.Expression;
                if (expression is SingleLeafExpressionNode singleLeafExpression)
                {
                    switch (type)
                    {
                    case CobaltType.Boolean:
                        if (singleLeafExpression.Leaf is BooleanValueNode booleanValue)
                        {
                            Assert.Equal((bool)value, booleanValue.Value);
                        }
                        else
                        {
                            throw new XunitException("Wrong Cobalt type.");
                        }
                        break;

                    case CobaltType.Float:
                        if (singleLeafExpression.Leaf is FloatValueNode floatValue)
                        {
                            Assert.Equal((float)value, floatValue.Value);
                        }
                        else
                        {
                            throw new XunitException("Wrong Cobalt type.");
                        }
                        break;

                    case CobaltType.Integer:
                        if (singleLeafExpression.Leaf is IntegerValueNode integerValue)
                        {
                            Assert.Equal((int)value, integerValue.Value);
                        }
                        else
                        {
                            throw new XunitException("Wrong Cobalt type.");
                        }
                        break;

                    default:
                        throw new XunitException("No test implemented for this type!");
                    }
                }
                else
                {
                    throw new XunitException("Wrong expression type.");
                }
            }
            else
            {
                throw new XunitException("Wrong node type.");
            }
        }