Ejemplo n.º 1
0
        private static AstStruct ParseStruct(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.Struct);
            var            ident           = tks.Expect(TokenType.Ident).StringValue;
            List <AstType> genericTypeList = null;

            if (tks.Accept(TokenType.LessThan) != null)
            {
                genericTypeList = ParseTypeList(tks, false, true);
                tks.Expect(TokenType.GreaterThan);
            }
            tks.Expect(TokenType.LCurBracket);
            var members = new List <AstDeclaration>();

            while (tks.Accept(TokenType.RCurBracket) == null)
            {
                var memberId = tks.Expect(TokenType.Ident).StringValue;
                tks.Expect(TokenType.Colon);

                var membType = ParseType(tks, true, true);

                tks.Expect(TokenType.Semicolon);
                members.Add(new AstDeclaration(si, memberId, membType, null));
            }
            return(new AstStruct(si, ident, members, genericTypeList));
        }
Ejemplo n.º 2
0
        // <foreign>            ::= 'foreign' 'func' <string> '(' <func-param-list> ')' ';'
        //                      |   'foreign' 'func' <string> '(' <func-param-list> ')' -> <ident> ';'
        private static AstForeign ParseForeign(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.Foreign);
            tks.Expect(TokenType.Func);
            var name  = tks.Expect(TokenType.Ident).StringValue;
            var cname = name;

            if (tks.Accept(TokenType.As) != null)
            {
                cname = tks.Accept(TokenType.String).WithoutQuotes();
            }
            tks.Expect(TokenType.LParen);
            var  paramList = ParseFuncParamList(tks);
            bool isVarArgs = tks.Accept(TokenType.DotDotDot) != null;

            tks.Expect(TokenType.RParen);

            var retType = tks.Accept(TokenType.RightArrow) != null
                ? ParseType(tks, false, false)
                : new AstType(si, "void", 0, 0, false, false);

            tks.Expect(TokenType.Semicolon);

            return(new AstForeign(si, paramList, name, cname, retType, isVarArgs));
        }
Ejemplo n.º 3
0
        private static bool ParseExtendParamList(TokenStream tks, string typeToExtend, List <AstDeclaration> @params)
        {
            var  si          = tks.SourceInfo;
            var  firstParam  = tks.Accept(TokenType.Ident);
            bool usesThisPtr = false;

            if (firstParam != null)
            {
                // no colon -> no type decl -> using thisptr
                AstType firstParType;
                if (tks.Accept(TokenType.Colon) == null)
                {
                    usesThisPtr = true;
                    if (tks.Peek().Type != TokenType.RParen)
                    {
                        tks.Expect(TokenType.Comma);
                    }
                    firstParType = new AstType(si, typeToExtend, 1, 0, false, false);
                }
                else
                {
                    firstParType = ParseType(tks, false, true);
                    if (tks.Peek().Type != TokenType.RParen)
                    {
                        tks.Expect(TokenType.Comma);
                    }
                }
                @params.Add(new AstDeclaration(si, firstParam.StringValue, firstParType, null));
                var otherParams = ParseFuncParamList(tks);
                @params.AddRange(otherParams);
            }
            return(usesThisPtr);
        }
Ejemplo n.º 4
0
        // <primary>            ::= '(' <expr> ')'
        //                      |   <number>
        //                      |   <ident>
        //                      |   <string>
        private static AstExpression ParsePrimary(TokenStream tks)
        {
            var si   = tks.SourceInfo;
            var save = tks.Index;
            var tk   = tks.Accept(TokenType.LParen);

            if (tk != null)
            {
                var expr = ParseAssign(tks);
                tks.Expect(TokenType.RParen);
                return(expr);
            }

            tk = tks.Accept(TokenType.Ident, TokenType.Number, TokenType.String);
            if (tk != null)
            {
                switch (tk.Type)
                {
                case TokenType.Ident:
                    return(new AstIdent(si, tk.StringValue));

                case TokenType.Number:
                    return(new AstNumber(si, tk.ToDecimal()));

                case TokenType.String:
                    return(new AstString(si, tk.StringValue));
                }
            }
            tks.Restore(save);
            return(null);
        }
Ejemplo n.º 5
0
        // <decl-assign>    ::= <ident> ':' <ident> '=' <assign>
        //                  |   <ident> ':' '=' <assign>
        //                  |   <ident> ':' <ident>
        //                  |   <ident> ':' <ident> [ <integer> ]
        private static AstDeclaration ParseVariableDeclaration(TokenStream tks)
        {
            var si    = tks.SourceInfo;
            var save  = tks.Index;
            var ident = tks.Accept(TokenType.Ident);

            if (ident == null)
            {
                tks.Restore(save);
                return(null);
            }
            if (tks.Accept(TokenType.Colon) == null)
            {
                tks.Restore(save);
                return(null);
            }
            AstType varType = null;

            if (tks.Peek().Type != TokenType.Assign)
            {
                varType = ParseType(tks, true, false);
            }

            AstExpression rhs = null;

            if (tks.Accept(TokenType.Assign) != null)
            {
                rhs = ParseAssign(tks);
                if (rhs == null)
                {
                    throw new Exception("Expected expression on rhs of variable declaration");
                }
            }
            return(new AstDeclaration(si, ident.StringValue, varType, rhs));
        }
Ejemplo n.º 6
0
        private static AstExpression ParseNewExpr(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.New);
            var what = tks.Expect(TokenType.Ident).StringValue;

            if (tks.Accept(TokenType.LParen) != null)
            {
                var ctorCall = new AstCall(si, new AstIdent(si, what), ParseExpressionList(tks));
                tks.Expect(TokenType.RParen);
                return(new AstUnaryOp(si, TokenType.New, ctorCall));
            }
            var ptrDepth = 1;

            while (tks.Accept(TokenType.Star) != null)
            {
                ptrDepth++;
            }
            tks.Expect(TokenType.LSquBracket);
            var size = ParseExpression(tks);

            tks.Expect(TokenType.RSquBracket);
            return(new AstNewArrayOp(si, size, what, ptrDepth));
        }
Ejemplo n.º 7
0
        // <if-stmt>        ::= 'if' <assign> '{' <body> '}'
        //                  ::= 'if' <assign> '{' <body> '}' 'else' '{' <body> '}'
        //                  ::= 'if' <assign> '{' <body> '}' 'else' <if-stmt>
        private static AstIf ParseIf(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.If);
            var cond = ParseAssign(tks);

            tks.Expect(TokenType.LCurBracket);
            var trueBody = ParseBody(tks);

            tks.Expect(TokenType.RCurBracket);
            var falseBody = new List <AstNode>();

            if (tks.Accept(TokenType.Else) != null)
            {
                if (tks.Accept(TokenType.LCurBracket) != null)
                {
                    falseBody = ParseBody(tks);
                    tks.Expect(TokenType.RCurBracket);
                }
                else
                {
                    tks.Expect(TokenType.If);
                    tks.Rewind();
                    falseBody.Add(ParseIf(tks));
                }
            }
            return(new AstIf(si, cond, trueBody, falseBody));
        }
Ejemplo n.º 8
0
        private bool ReturnStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "return"))
            {
                return(false);
            }

            if (IsReference(TokenStream.Peek()) || TokenStream.Pass(TokenType.Number) || TokenStream.Pass(TokenType.String) ||
                (TokenStream.Pass(TokenType.Delimiter) && !TokenStream.Accept(TokenType.Delimiter, ";")))
            {
                if (currentMethod.Name == IdentConstructor)
                {
                    throw new CompilerException("Constructors must return a 'this' pointer.");
                }

                Ternary();
            }
            else if (currentMethod.Name == IdentConstructor)
            {
                Instructions.Add(new Instruction(Opcode.GetThis));
            }

            Instructions.Add(new Instruction(Opcode.Return));

            TokenStream.Accept(TokenType.Delimiter, ";");

            return(true);
        }
Ejemplo n.º 9
0
        private static AstFor ParseForIn(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.For);
            var ident = tks.Expect(TokenType.Ident).StringValue;

            tks.Expect(TokenType.In);
            var @from = ParseExpression(tks);

            tks.Expect(TokenType.DotDot);
            var to       = ParseExpression(tks);
            var opTk     = tks.Accept(TokenType.Plus, TokenType.Minus);
            var updateOp = opTk?.Type ?? TokenType.Plus;

            tks.Expect(TokenType.LCurBracket);
            var body = ParseBody(tks);

            tks.Expect(TokenType.RCurBracket);

            var pre    = new AstDeclaration(si, ident, null, @from);
            var condOp = (updateOp == TokenType.Plus)
                    ? TokenType.LessThanEquals
                    : TokenType.GreaterThanEquals;
            var itrId   = new AstIdent(si, ident);
            var cond    = new AstBinaryOp(si, itrId, condOp, to);
            var update_ = new AstBinaryOp(si, itrId, updateOp, new AstNumber(si, 1));
            var update  = new AstAssign(si, itrId, update_);

            return(new AstFor(si, new List <AstNode> {
                pre
            }, cond, new List <AstExpression> {
                update
            }, body));
        }
Ejemplo n.º 10
0
        private void PrimaryReference()
        {
            int refIndex = TokenStream.Position;

            GetReference();

            if (TokenStream.Accept(TokenType.Delimiter, "++"))
            {
                TokenStream.Position = refIndex;
                GetReference();
                Instructions.Add(new Instruction(Opcode.Push, 1));
                Instructions.Add(new Instruction(Opcode.Add));
                TokenStream.Position = refIndex;
                SetReference();

                TokenStream.Read();
            }
            else if (TokenStream.Accept(TokenType.Delimiter, "--"))
            {
                TokenStream.Position = refIndex;
                GetReference();
                Instructions.Add(new Instruction(Opcode.Push, 1));
                Instructions.Add(new Instruction(Opcode.Subtract));
                TokenStream.Position = refIndex;
                SetReference();

                TokenStream.Read();
            }
        }
Ejemplo n.º 11
0
 private void PrefixIncrement()
 {
     if (TokenStream.Accept(TokenType.Delimiter, "++"))
     {
         TokenStream.PushPosition();
         GetReference();
         Instructions.Add(new Instruction(Opcode.Push, 1));
         Instructions.Add(new Instruction(Opcode.Add));
         TokenStream.PopPosition();
         TokenStream.PushPosition();
         SetReference();
         TokenStream.PopPosition();
         GetReference();
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "--"))
     {
         TokenStream.PushPosition();
         GetReference();
         Instructions.Add(new Instruction(Opcode.Push, 1));
         Instructions.Add(new Instruction(Opcode.Subtract));
         TokenStream.PopPosition();
         TokenStream.PushPosition();
         SetReference();
         TokenStream.PopPosition();
         GetReference();
     }
 }
Ejemplo n.º 12
0
 private void Unary()
 {
     if (Parser.IsAddOperation(TokenStream.Peek()))
     {
         UnarySign();
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "!"))
     {
         Primary();
         Instructions.Add(new Instruction(Opcode.BitwiseNot));
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "~"))
     {
         Primary();
         Instructions.Add(new Instruction(Opcode.BitwiseNegate));
     }
     else if (Parser.IsCastOperation(TokenStream.Peek()))
     {
         TypeCast();
     }
     else if (Parser.IsIncrementOperation(TokenStream.Peek()))
     {
         PrefixIncrement();
     }
     else
     {
         Primary();
     }
 }
Ejemplo n.º 13
0
        private void Multiplicative()
        {
            Unary();

            while (Parser.IsMulOperation(TokenStream.Peek()))
            {
                if (TokenStream.Accept(TokenType.Delimiter, "*"))
                {
                    Unary();
                    Instructions.Add(new Instruction(Opcode.Multiply));
                }
                else if (TokenStream.Accept(TokenType.Delimiter, "/"))
                {
                    Unary();
                    Instructions.Add(new Instruction(Opcode.Divide));
                }
                else if (TokenStream.Accept(TokenType.Delimiter, "%"))
                {
                    if (TokenStream.Pass(TokenType.Delimiter, "["))
                    {
                        // Write hacks err day
                        Ternary();
                        Instructions.Add(new Instruction(Opcode.ClassCallStatic, "__str Format", 2));
                    }
                    else
                    {
                        Unary();
                        Instructions.Add(new Instruction(Opcode.Modulo));
                    }
                }
            }
        }
Ejemplo n.º 14
0
        private void Ternary()
        {
            LogicalOr();

            while (TokenStream.Accept(TokenType.Delimiter, "?"))
            {
                Label labelElse = new Label(this);
                Label labelEnd  = new Label(this);

                Instructions.Add(new Instruction(Opcode.Push, 0));
                Instructions.Add(new Instruction(Opcode.CompareNotEqual));
                Instructions.Add(new Instruction(Opcode.IfFalse, 0));
                labelElse.PatchHere();

                LogicalOr();
                Instructions.Add(new Instruction(Opcode.Jump, 0));
                labelEnd.PatchHere();

                TokenStream.Expect(TokenType.Delimiter, ":");

                labelElse.Mark();
                LogicalOr();
                labelEnd.Mark();

                labelElse.Fix();
                labelEnd.Fix();
            }
        }
Ejemplo n.º 15
0
        private bool BreakStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "break"))
            {
                return(false);
            }

            if (breakStack.Count == 0)
            {
                throw new CompilerException("Nothing to break from.");
            }

            if (TokenStream.Pass(TokenType.Number))
            {
                long count = TokenStream.ReadVariant().IntValue;
                if (breakStack.Count < count)
                {
                    throw new CompilerException("Cannot break from {0} scopes deep, because we are not {0} scopes deep at this time.", count);
                }

                Instructions.Add(new Instruction(Opcode.Jump, 0));
                Label[] labelArray = breakStack.ToArray();
                labelArray[count - 1].PatchHere();
            }
            else
            {
                Instructions.Add(new Instruction(Opcode.Jump, 0));
                breakStack.Peek().PatchHere();
            }

            TokenStream.Accept(TokenType.Delimiter, ";");

            return(true);
        }
Ejemplo n.º 16
0
        // <unary-exp>          ::= <postfix-exp>
        //                      |   <unary-op> <unary-exp>
        private static AstExpression ParseUnaryOp(TokenStream tks)
        {
            var si      = tks.SourceInfo;
            var save    = tks.Index;
            var postfix = ParsePostfix(tks);

            if (postfix != null)
            {
                return(postfix);
            }
            tks.Restore(save);
            var op = tks.Accept(UnaryOps);

            if (op == null)
            {
                tks.Restore(save);
                return(null);
            }
            if (op.Type == TokenType.New)
            {
                tks.Restore(save);
                return(ParseNewExpr(tks));
            }
            var unary = ParseUnaryOp(tks);

            return(new AstUnaryOp(si, op.Type, unary));
        }
Ejemplo n.º 17
0
        private bool ForStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "for"))
            {
                return(false);
            }

            Label labelStart    = new Label(this);
            Label labelEnd      = new Label(this);
            Label labelContinue = new Label(this);

            continueStack.Push(labelContinue);
            breakStack.Push(labelEnd);

            TokenStream.Expect(TokenType.Delimiter, "(");
            if (!Variable())
            {
                Assignment();
            }

            TokenStream.Accept(TokenType.Delimiter, ";");

            labelStart.Mark();
            Assignment();
            Instructions.Add(new Instruction(Opcode.Push, 1));
            Instructions.Add(new Instruction(Opcode.CompareNotEqual));
            Instructions.Add(new Instruction(Opcode.IfTrue, 0));
            labelEnd.PatchHere();
            TokenStream.Accept(TokenType.Delimiter, ";");

            TokenStream.PushPosition();
            while (!TokenStream.Accept(TokenType.Delimiter, ")"))
            {
                TokenStream.Read();
            }

            Block();
            int endOfBlock = TokenStream.Position;

            TokenStream.PopPosition();
            labelContinue.Mark();
            Assignment();
            TokenStream.Position = endOfBlock;

            Instructions.Add(new Instruction(Opcode.Jump, 0));
            labelStart.PatchHere();
            labelEnd.Mark();

            labelContinue.Fix();
            labelStart.Fix();
            labelEnd.Fix();
            continueStack.Pop();
            breakStack.Pop();

            return(true);
        }
Ejemplo n.º 18
0
        private void BitwiseXor()
        {
            BitwiseAnd();

            while (TokenStream.Accept(TokenType.Delimiter, "^"))
            {
                BitwiseAnd();
                Instructions.Add(new Instruction(Opcode.BitwiseXor));
            }
        }
Ejemplo n.º 19
0
        private void BitwiseAnd()
        {
            Equality();

            while (TokenStream.Accept(TokenType.Delimiter, "&"))
            {
                Equality();
                Instructions.Add(new Instruction(Opcode.BitwiseAnd));
            }
        }
Ejemplo n.º 20
0
 private void BlockStatement()
 {
     if (!IfStatement() && !WhileStatement() && !DoWhileStatement() && !ForeachStatement() &&
         !ForStatement() && !SwitchStatement() && !RepeatStatement() &&
         !ReturnStatement() && !BreakStatement() && !ContinueStatement() &&
         !Variable())
     {
         Assignment();
         TokenStream.Accept(TokenType.Delimiter, ";");
     }
 }
Ejemplo n.º 21
0
        private void LogicalOr()
        {
            LogicalAnd();

            while (TokenStream.Accept(TokenType.Delimiter, "||"))
            {
                LogicalAnd();
                Instructions.Add(new Instruction(Opcode.Add));
                Instructions.Add(new Instruction(Opcode.Push, 0));
                Instructions.Add(new Instruction(Opcode.CompareGreaterThan));
            }
        }
Ejemplo n.º 22
0
        private void LogicalAnd()
        {
            BitwiseOr();

            while (TokenStream.Accept(TokenType.Delimiter, "&&"))
            {
                BitwiseOr();
                Instructions.Add(new Instruction(Opcode.Add));
                Instructions.Add(new Instruction(Opcode.Push, 2));
                Instructions.Add(new Instruction(Opcode.CompareEqual));
            }
        }
Ejemplo n.º 23
0
        // <type>           ::= '#' ? <ident> '*'* '[' <integer> ']'
        //                  ::= 'ref' '#'? <ident> '*'* '[' <integer> ']'
        private static AstType ParseType(TokenStream tks, bool allowFixedArray, bool allowGeneric)
        {
            var  si           = tks.Peek().SourceInfo;
            bool isAReference = tks.Accept(TokenType.Ref) != null;
            bool isGeneric    = tks.Accept(TokenType.Hash) != null;
            var  ident        = tks.Expect(TokenType.Ident).StringValue;
            var  ptrDepth     = 0;

            while (tks.Accept(TokenType.Star) != null)
            {
                ++ptrDepth;
            }
            int fixedSize = 0;

            if (tks.Accept(TokenType.LSquBracket) != null)
            {
                var size = tks.Expect(TokenType.Number);
                if (!size.IsIntegral())
                {
                    throw new UnexpectedTokenException(
                              TokenType.Number,
                              string.Format(
                                  "Error: {0} : Expected integral number, got `{1}'",
                                  size.SourceInfo, size.StringValue));
                }
                ++ptrDepth;
                fixedSize = (int)size.ToDecimal();
                tks.Expect(TokenType.RSquBracket);
            }
            if (!allowFixedArray && fixedSize != 0)
            {
                throw new NotImplementedException(string.Format("{0} : Fixed array not allowed here.", si));
            }
            if (!allowGeneric && isGeneric)
            {
                throw new NotImplementedException(string.Format("{0} : Generic type not allowed here.", si));
            }
            return(new AstType(si, ident, ptrDepth, fixedSize, isAReference, isGeneric));
        }
Ejemplo n.º 24
0
        private static AstExtend ParseExtend(TokenStream tks)
        {
            var save = tks.Index;
            var si   = tks.SourceInfo;

            tks.Expect(TokenType.Extend);
            if (tks.Accept(TokenType.ArithNot) != null)
            {
                // destructor
                tks.Restore(save);
                return(ParseDestructor(tks));
            }
            var typeToExtend = tks.Expect(TokenType.Ident).StringValue;

            if (tks.Accept(TokenType.LParen) != null)
            {
                // constructor
                tks.Restore(save);
                return(ParseConstructor(tks));
            }
            var name = tks.Expect(TokenType.Ident).StringValue;

            tks.Expect(TokenType.LParen);
            var @params     = new List <AstDeclaration>();
            var usesThisPtr = ParseExtendParamList(tks, typeToExtend, @params);

            tks.Expect(TokenType.RParen);

            var retType = tks.Accept(TokenType.RightArrow) != null
                ? ParseType(tks, false, true)
                : new AstType(si, "void", 0, 0, false, false);

            tks.Expect(TokenType.LCurBracket);
            var body = ParseBody(tks);

            tks.Expect(TokenType.RCurBracket);
            return(new AstExtend(si, typeToExtend, name, usesThisPtr, @params, retType, body));
        }
Ejemplo n.º 25
0
        private static List <AstType> ParseTypeList(TokenStream tks, bool allowFixedArray, bool allowGenerics)
        {
            var list = new List <AstType>();

            while (true)
            {
                var type = ParseType(tks, allowFixedArray, allowGenerics);
                list.Add(type);
                if (tks.Accept(TokenType.Comma) == null)
                {
                    return(list);
                }
            }
        }
Ejemplo n.º 26
0
        private static List <AstDeclaration> ParseFuncParamList(TokenStream tks)
        {
            var si         = tks.SourceInfo;
            var parameters = new List <AstDeclaration>();

            while (true)
            {
                var ident = tks.Accept(TokenType.Ident);
                if (ident != null)
                {
                    tks.Expect(TokenType.Colon);

                    var parType = ParseType(tks, false, true);
                    parameters.Add(new AstDeclaration(si, ident.StringValue, parType, null));
                    if (tks.Accept(TokenType.Comma) != null)
                    {
                        continue;
                    }
                }
                break;
            }
            return(parameters);
        }
Ejemplo n.º 27
0
        private bool Variable()
        {
            if (TokenStream.Peek().Value != "var")
            {
                return(false);
            }

            TokenStream.Expect("var");
            do
            {
                int identOffset = TokenStream.Position;

                string ident = TokenStream.ReadWord();
                if (IsVariableInScope(ident) || IsField(ident) || IsMethod(ident) || IsConstant(ident) || IsEnumeration(ident))
                {
                    throw new CompilerException("Redeclaration of variable '{0}' in method '{1}'.", ident, currentMethod.Name);
                }

                if (Parser.IsReservedIdent(ident))
                {
                    throw new CompilerException("'{0}' is a reserved symbol.", ident);
                }

                Variant value = ParseAnnotatedVariable();

                // This should be safe, if we don't have the variable in scope but it's already been created in a previous scope
                // then we don't want to readd it, just reference it (it will already be allocated on the stack).
                if (!IsVariable(ident))
                {
                    currentMethod.Variables.Add(ident, value);
                }

                scopeStack.Peek().Add(ident);

                if (TokenStream.Accept(TokenType.Delimiter, "="))
                {
                    TokenStream.Position = identOffset;
                    Assignment();
                }
                else
                {
                    Instructions.Add(new Instruction(Opcode.Push, value));
                    Instructions.Add(new Instruction(Opcode.SetVariable, ident));
                }
            }while (TokenStream.Accept(TokenType.Delimiter, ","));

            TokenStream.Accept(TokenType.Delimiter, ";");

            return(true);
        }
Ejemplo n.º 28
0
        // <require>        ::= 'require' <package-ident> ';'
        //                  |   'require' <package-ident> '.' '*' ';'
        private static AstRequire ParseRequire(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.Require);
            var  idents   = ParsePackageIdent(tks);
            bool usesStar = false;

            if (tks.Accept(TokenType.Dot) != null)
            {
                tks.Expect(TokenType.Star);
                usesStar = true;
            }
            tks.Expect(TokenType.Semicolon);
            return(new AstRequire(si, idents, usesStar));
        }
Ejemplo n.º 29
0
        private Variant ParseAnnotatedVariable()
        {
            if (!TokenStream.Accept(TokenType.Delimiter, ":"))
            {
                return(new Variant());
            }

            string type = TokenStream.ReadWord();

            switch (type)
            {
            case "nil":
                return(new Variant());

            case "int":
                return(new Variant(0));

            case "double":
                return(new Variant(0.0));

            case "str":
                return(new Variant("")
                {
                    ObjectName = "__str"
                });

            case "list":
                return(new Variant(new List <Variant>())
                {
                    ObjectName = "__list"
                });

            case "object":
                return(new Variant((object)null));

            default:
                if (!IsClass(type))
                {
                    throw new CompilerException("'{0}' is not a valid variant type.", type);
                }

                return(new Variant((object)null)
                {
                    ObjectName = type
                });
            }
        }
Ejemplo n.º 30
0
        private void NewObject(Class parent)
        {
            // Call constructor if there is one
            if (IsMethod(IdentConstructor, parent))
            {
                // Parse arguments
                int argumentsPassed = ArgumentList();

                Method method = GetMethod(IdentConstructor, argumentsPassed, parent);

                if (GetMethod(IdentConstructor, parent) == null)
                {
                    throw new CompilerException("Class '{0}' has no constructor.", parent.Name);
                }

                if (method == null)
                {
                    throw new CompilerException("No overload of class '{0}''s constructor accepts {1} arguments.",
                                                parent.Name, argumentsPassed);
                }

                // Create new object and call constructor
                Instructions.Add(new Instruction(Opcode.New, parent.Name));
                Instructions.Add(new Instruction(Opcode.ClassCall, IdentConstructor, argumentsPassed));
            }
            else
            {
                // Create new object
                Instructions.Add(new Instruction(Opcode.New, parent.Name));

                // No constructor, read useless argument list
                TokenStream.Expect(TokenType.Delimiter, "(");
                TokenStream.Expect(TokenType.Delimiter, ")");
            }

            // Push this object type onto the type stack so the reference can be evaluated later
            typeStack.Push(parent.Name);

            // Parse out inline method calls
            if (TokenStream.Accept(TokenType.Delimiter, "."))
            {
                string tmpVarIdent = CreateTemporaryVariable();
                Instructions.Add(new Instruction(Opcode.SetVariable, tmpVarIdent));
                MethodCall(parent, new Instruction(Opcode.GetVariable, tmpVarIdent));
            }
        }