Beispiel #1
0
        public Expression Parse(LoonyParser parser, LoonyToken token)
        {
            var expression = parser.ParseExpression();

            parser.Take(LoonyTokenType.RightParen);
            return(expression);
        }
Beispiel #2
0
 public BinaryOperatorExpression(LoonyToken token, Expression left, Expression right)
     : base(token)
 {
     Operation = token.Type;
     Left      = left;
     Right     = right;
 }
Beispiel #3
0
        public Statement Parse(LoonyParser parser, LoonyToken token, out bool trailingSemicolon)
        {
            trailingSemicolon = true;

            var value = parser.ParseExpression();
            return new ReturnStatement(token, parser.Previous, value);
        }
Beispiel #4
0
        public Statement Parse(LoonyParser parser, LoonyToken token, out bool trailingSemicolon)
        {
            trailingSemicolon = true;

            var        name        = parser.Take(LoonyTokenType.Identifier).Contents;
            TypeBase   type        = null;
            Expression initializer = null;

            if (parser.MatchAndTake(LoonyTokenType.Colon))
            {
                type = parser.ParseType();
            }

            if (type == null)
            {
                parser.Take(LoonyTokenType.Assign);
                initializer = parser.ParseExpression();
            }
            else if (parser.MatchAndTake(LoonyTokenType.Assign))
            {
                initializer = parser.ParseExpression();
            }

            return(new VariableStatement(token, parser.Previous, name, type, initializer));
        }
Beispiel #5
0
        public Declaration Parse(LoonyParser parser, LoonyToken token)
        {
            var start = token;

            var      name       = parser.Take(LoonyTokenType.Identifier);
            var      parameters = new List <FuncDeclaration.Parameter>();
            TypeBase returnType = null;

            parser.Take(LoonyTokenType.LeftParen);

            if (!parser.MatchAndTake(LoonyTokenType.RightParen))
            {
                do
                {
                    var paramName = parser.Take(LoonyTokenType.Identifier);
                    parser.Take(LoonyTokenType.Colon);
                    var paramType = parser.ParseType();

                    parameters.Add(new FuncDeclaration.Parameter(paramName, paramType));
                } while (parser.MatchAndTake(LoonyTokenType.Comma));

                parser.Take(LoonyTokenType.RightParen);
            }

            if (parser.MatchAndTake(LoonyTokenType.Colon))
            {
                returnType = parser.ParseType();
            }

            var body = parser.ParseBlock(false);

            var end = parser.Previous;

            return(new FuncDeclaration(start, end, name, parameters, returnType, body));
        }
Beispiel #6
0
        public Declaration Parse(LoonyParser parser, LoonyToken token)
        {
            var start = token;

            var name = parser.Take(LoonyTokenType.Identifier);
            var parameters = new List<FuncDeclaration.Parameter>();
            TypeBase returnType = null;

            parser.Take(LoonyTokenType.LeftParen);

            if (!parser.MatchAndTake(LoonyTokenType.RightParen))
            {
                do
                {
                    var paramName = parser.Take(LoonyTokenType.Identifier);
                    parser.Take(LoonyTokenType.Colon);
                    var paramType = parser.ParseType();

                    parameters.Add(new FuncDeclaration.Parameter(paramName, paramType));
                } while (parser.MatchAndTake(LoonyTokenType.Comma));

                parser.Take(LoonyTokenType.RightParen);
            }

            if (parser.MatchAndTake(LoonyTokenType.Colon))
                returnType = parser.ParseType();

            var body = parser.ParseBlock(false);

            var end = parser.Previous;

            return new FuncDeclaration(start, end, name, parameters, returnType, body);
        }
Beispiel #7
0
        public Statement Parse(LoonyParser parser, LoonyToken token, out bool trailingSemicolon)
        {
            trailingSemicolon = true;

            var value = parser.ParseExpression();

            return(new ReturnStatement(token, parser.Previous, value));
        }
Beispiel #8
0
 public FuncDeclaration(LoonyToken start, LoonyToken end, LoonyToken name, IEnumerable <Parameter> parameters, TypeBase returnType, BlockStatement body)
     : base(start, end)
 {
     Name       = name;
     Parameters = parameters.ToList().AsReadOnly();
     ReturnType = returnType;
     Body       = body;
 }
Beispiel #9
0
        protected Declaration(LoonyToken start, LoonyToken end = null)
        {
            if (start == null)
            {
                throw new ArgumentNullException(nameof(start));
            }

            Start = start;
            End   = end ?? start;
        }
Beispiel #10
0
        public IdentifierExpression(LoonyToken token, string name)
            : base(token)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            Name = name;
        }
Beispiel #11
0
        public BlockStatement(LoonyToken start, LoonyToken end, IEnumerable <Statement> statements)
            : base(start, end)
        {
            if (statements == null)
            {
                throw new ArgumentNullException(nameof(statements));
            }

            Statements = statements.ToList().AsReadOnly();
        }
Beispiel #12
0
        public override Expression Visit(BinaryOperatorExpression expression)
        {
            var left  = expression.Left.Accept(this);
            var right = expression.Right.Accept(this);

            var leftNum  = left as NumberExpression;
            var rightNum = right as NumberExpression;

            if (leftNum == null && rightNum == null)
            {
                return(new BinaryOperatorExpression(expression.Start, left, right));
            }

            // n <op> n
            Func <int, int, int> simplifyOp;

            if (_simplifyMap.TryGetValue(expression.Operation, out simplifyOp) &&
                leftNum != null &&
                rightNum != null)
            {
                try
                {
                    var result = simplifyOp(leftNum.Value, rightNum.Value);
                    var token  = new LoonyToken(expression.Start, LoonyTokenType.Number, null);
                    return(new NumberExpression(token, result));
                }
                catch (DivideByZeroException)
                {
                    throw new CompilerException(expression.Start, CompilerError.DivisionByZero);
                }
            }

            // 0 + e || e + 0
            if (expression.Operation == LoonyTokenType.Add)
            {
                if (leftNum != null && leftNum.Value == 0)
                {
                    return(right);
                }

                if (rightNum != null && rightNum.Value == 0)
                {
                    return(left);
                }
            }

            return(new BinaryOperatorExpression(expression.Start, left, right));
        }
Beispiel #13
0
        public VariableStatement(LoonyToken start, LoonyToken end, string name, TypeBase type, Expression initializer)
            : base(start, end)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (type == null && initializer == null)
            {
                throw new ArgumentNullException(nameof(initializer), "initializer can't be null when no type is specified");
            }

            Name        = name;
            Type        = type;
            Initializer = initializer;
        }
Beispiel #14
0
        public override Expression Visit(BinaryOperatorExpression expression)
        {
            var left = expression.Left.Accept(this);
            var right = expression.Right.Accept(this);

            var leftNum = left as NumberExpression;
            var rightNum = right as NumberExpression;

            if (leftNum == null && rightNum == null)
                return new BinaryOperatorExpression(expression.Start, left, right);

            // n <op> n
            Func<int, int, int> simplifyOp;
            if (_simplifyMap.TryGetValue(expression.Operation, out simplifyOp) &&
                leftNum != null &&
                rightNum != null)
            {
                try
                {
                    var result = simplifyOp(leftNum.Value, rightNum.Value);
                    var token = new LoonyToken(expression.Start, LoonyTokenType.Number, null);
                    return new NumberExpression(token, result);
                }
                catch (DivideByZeroException)
                {
                    throw new CompilerException(expression.Start, CompilerError.DivisionByZero);
                }
            }

            // 0 + e || e + 0
            if (expression.Operation == LoonyTokenType.Add)
            {
                if (leftNum != null && leftNum.Value == 0)
                    return right;

                if (rightNum != null && rightNum.Value == 0)
                    return left;
            }

            return new BinaryOperatorExpression(expression.Start, left, right);
        }
Beispiel #15
0
        public Statement Parse(LoonyParser parser, LoonyToken token, out bool trailingSemicolon)
        {
            trailingSemicolon = true;

            var name = parser.Take(LoonyTokenType.Identifier).Contents;
            TypeBase type = null;
            Expression initializer = null;

            if (parser.MatchAndTake(LoonyTokenType.Colon))
                type = parser.ParseType();

            if (type == null)
            {
                parser.Take(LoonyTokenType.Assign);
                initializer = parser.ParseExpression();
            }
            else if (parser.MatchAndTake(LoonyTokenType.Assign))
            {
                initializer = parser.ParseExpression();
            }

            return new VariableStatement(token, parser.Previous, name, type, initializer);
        }
Beispiel #16
0
 public Expression Parse(LoonyParser parser, LoonyToken token)
 {
     var value = int.Parse(token.Contents);
     return new NumberExpression(token, value);
 }
Beispiel #17
0
 public ReturnStatement(LoonyToken start, LoonyToken end, Expression value)
     : base(start, end)
 {
     Value = value;
 }
Beispiel #18
0
 public Expression Parse(LoonyParser parser, LoonyToken token)
 {
     var expression = parser.ParseExpression();
     parser.Take(LoonyTokenType.RightParen);
     return expression;
 }
Beispiel #19
0
 public Expression Parse(LoonyParser parser, LoonyToken token)
 {
     return new IdentifierExpression(token, token.Contents);
 }
Beispiel #20
0
        /// <summary>
        /// Take a token from the stream.
        /// </summary>
        public LoonyToken Take()
        {
            Peek();

            var result = _read[0];
            _read.RemoveAt(0);

            Previous = result;

            return result;
        }
 public Expression Parse(LoonyParser parser, Expression left, LoonyToken token)
 {
     var right = parser.ParseExpression(Precedence - (_isRight ? 1 : 0));
     return new BinaryOperatorExpression(token, left, right);
 }
Beispiel #22
0
 public StructDeclaration(LoonyToken start, LoonyToken end)
     : base(start, end)
 {
 }
Beispiel #23
0
 public Parameter(LoonyToken name, TypeBase type)
 {
     Name = name;
     Type = type;
 }
Beispiel #24
0
 public Expression Parse(LoonyParser parser, LoonyToken token)
 {
     return(new IdentifierExpression(token, token.Contents));
 }
Beispiel #25
0
        public Expression Parse(LoonyParser parser, LoonyToken token)
        {
            var value = int.Parse(token.Contents);

            return(new NumberExpression(token, value));
        }
Beispiel #26
0
        static LoonyLexer()
        {
            EofToken = new LoonyToken(null, default(SourcePosition), default(SourcePosition), LoonyTokenType.Eof, null);

            _operators = new OperatorDictionary<LoonyTokenType>
            {
                { ";", LoonyTokenType.Semicolon },
                { ",", LoonyTokenType.Comma },
                { ".", LoonyTokenType.Dot },
                { "=", LoonyTokenType.Assign },
                { "?", LoonyTokenType.QuestionMark },
                { ":", LoonyTokenType.Colon },
                { "->", LoonyTokenType.Pointy },

                { "(", LoonyTokenType.LeftParen },
                { ")", LoonyTokenType.RightParen },

                { "{", LoonyTokenType.LeftBrace },
                { "}", LoonyTokenType.RightBrace },

                { "[", LoonyTokenType.LeftSquare },
                { "]", LoonyTokenType.RightSquare },

                { "+", LoonyTokenType.Add },
                { "+=", LoonyTokenType.AddAssign },
                { "-", LoonyTokenType.Subtract },
                { "-=", LoonyTokenType.SubtractAssign },
                { "*", LoonyTokenType.Multiply },
                { "*=", LoonyTokenType.MultiplyAssign },
                { "/", LoonyTokenType.Divide },
                { "/=", LoonyTokenType.DivideAssign },
                { "%", LoonyTokenType.Remainder },
                { "%=", LoonyTokenType.RemainderAssign },
                { "++", LoonyTokenType.Increment },
                { "--", LoonyTokenType.Decrement },

                { "==", LoonyTokenType.EqualTo },
                { "!=", LoonyTokenType.NotEqualTo },
                { ">", LoonyTokenType.GreaterThan },
                { ">=", LoonyTokenType.GreaterThanOrEqual },
                { "<", LoonyTokenType.LessThan },
                { "<=", LoonyTokenType.LessThanOrEqual },

                { "&&", LoonyTokenType.LogicalAnd },
                { "||", LoonyTokenType.LogicalOr },
                { "!", LoonyTokenType.LogicalNot },

                { "~", LoonyTokenType.BitwiseNot },
                { "&", LoonyTokenType.BitwiseAnd },
                { "&=", LoonyTokenType.BitwiseAndAssign },
                { "|", LoonyTokenType.BitwiseOr },
                { "|=", LoonyTokenType.BitwiseOrAssign },
                { "^", LoonyTokenType.BitwiseXor },
                { "^=", LoonyTokenType.BitwiseXorAssign },
                { "<<", LoonyTokenType.BitwiseShiftLeft },
                { "<<=", LoonyTokenType.BitwiseShiftLeftAssign },
                { ">>", LoonyTokenType.BitwiseShiftRight },
                { ">>=", LoonyTokenType.BitwiseShiftRightAssign },
            };

            _keywords = new Dictionary<string, LoonyTokenType>
            {
                { "null", LoonyTokenType.Null },
                { "true", LoonyTokenType.True },
                { "false", LoonyTokenType.False },

                { "any", LoonyTokenType.Any },
                { "bool", LoonyTokenType.Bool },
                { "char", LoonyTokenType.Char },
                { "short", LoonyTokenType.Short },
                { "int", LoonyTokenType.Int },

                { "var", LoonyTokenType.Var },
                { "return", LoonyTokenType.Return },
                { "if", LoonyTokenType.If },
                { "else", LoonyTokenType.Else },
                { "for", LoonyTokenType.For },
                { "while", LoonyTokenType.While },
                { "do", LoonyTokenType.Do },
                { "break", LoonyTokenType.Break },
                { "continue", LoonyTokenType.Continue },

                { "const", LoonyTokenType.Const },
                { "static", LoonyTokenType.Static },
                { "func", LoonyTokenType.Func },
                { "struct", LoonyTokenType.Struct },
                { "union", LoonyTokenType.Union },
                { "extern", LoonyTokenType.Extern },
            };
        }
Beispiel #27
0
 public NumberExpression(LoonyToken token, int value)
     : base(token)
 {
     Value = value;
 }
        public Expression Parse(LoonyParser parser, Expression left, LoonyToken token)
        {
            var right = parser.ParseExpression(Precedence - (_isRight ? 1 : 0));

            return(new BinaryOperatorExpression(token, left, right));
        }
Beispiel #29
0
 internal CompilerException(LoonyToken token, string format, params object[] args)
     : base($"{token.FileName ?? "null"}({token.RangeString}): {string.Format(format, args)}")
 {
 }