예제 #1
0
        private void ParseStructDeclarationList()
        {
            Symbols.Type type     = null;
            Symbols.Var  variable = null;
            Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > pair = null;

            while (IsType(scan.Peek()) && (type = ParseTypeSpecifier()) != null)
            {
                while (true)
                {
                    pair     = ParseDeclarator();
                    variable = pair.first;
                    if (pair.last == null)
                    {
                        variable.SetType(type);
                    }
                    else
                    {
                        pair.last.last.SetType(type);
                        variable.SetType(pair.last.first);
                    }
                    tstack.AddSymbol(variable);
                    if (scan.Peek().type != Token.Type.COMMA)
                    {
                        break;
                    }
                    scan.Read();
                }

                CheckToken(scan.Peek(), Token.Type.SEMICOLON, true);
            }
        }
예제 #2
0
            private static Pair <Expression, Expression> UsualArithmeticConversions(
                Expression lop, Expression rop)
            {
                Symbols.Type lt = lop.GetType(), rt = rop.GetType();

                if (lt is Symbols.DOUBLE || rt is Symbols.DOUBLE)
                {
                    if (rt != lt)
                    {
                        if (lt is Symbols.DOUBLE)
                        {
                            rop = new Cast(rop, lt);
                        }
                        else
                        {
                            lop = new Cast(lop, rt);
                        }
                    }
                }
                else if (lt is Symbols.CHAR && rt is Symbols.INT)
                {
                    lop = new Cast(lop, rt);
                }
                else if (rt is Symbols.CHAR && lt is Symbols.INT)
                {
                    rop = new Cast(rop, lt);
                }

                return(new Pair <Expression, Expression>(lop, rop));
            }
예제 #3
0
파일: Parser.cs 프로젝트: Deliay/SuperBasic
        private Param Param()
        {
            bool isOpt = Except(Tag.OPTIONAL);
            Word name  = look as Word;

            ExceptGrammar(Tag.IDENTITY);
            ExceptGrammar(Tag.AS);
            Symbols.Type type = look as Symbols.Type;
            ExceptGrammar(Tag.BASICTYPE);
            if (isOpt && ExceptGrammar(Tag.Equal))
            {
                Expr initVal = Expr();
                if (!(initVal is Constant))
                {
                    throw new TokenNotConstantException(initVal);
                }
                Except(Tag.Split);
                return(new OptParam(name, type, initVal as Constant));
            }
            else
            {
                Except(Tag.Split);
                return(new Param(name, type));
            }
        }
예제 #4
0
        private Symbols.ParamVar ParseParameterDeclaration()
        {
            Token first_token = scan.Peek();

            Symbols.Type     type     = ParseTypeSpecifier();
            Symbols.ParamVar variable = null;

            if (type != null)
            {
                Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > res;
                res      = ParseDeclarator(parse_parameter: true);
                variable = (Symbols.ParamVar)res.first;

                if (res.last != null)
                {
                    res.last.last.SetType(type);
                    type = res.last.first;
                }

                if (type is Symbols.VOID)
                {
                    this.logger.Add(new Symbols.Exception("недопустимо использование типа \"void\"",
                                                          first_token.GetIndex(), first_token.GetLine()));
                    type = new Symbols.SuperType();
                }

                if (variable == null)
                {
                    variable = new Symbols.ParamVar("", type.GetIndex(), type.GetLine());
                }
            }
            variable.SetType(type);
            return(variable);
        }
예제 #5
0
 public Id(Word id, SymbolTable t, Symbols.Type p, int b, bool s) : base(id, p)
 {
     Offset    = b;
     Scope     = t;
     IsStatic  = s;
     Identity  = id;
     IsInitial = false;
 }
예제 #6
0
 public Params(int line, IEnumerable <Param> args, Symbols.Type retType) : base(line)
 {
     ParamList  = args;
     ReturnType = retType;
     if (ReturnType == null)
     {
         ReturnType = ReserveType.Void;
     }
 }
예제 #7
0
        public void Value(Symbols.Type t_val)
        {
            Reg r = GetFreeReg();

            AddCode(Com.POP, new Addr(r));
            if (t_val is Symbols.INT || t_val is Symbols.POINTER || t_val is Symbols.CHAR)
            {
                AddCode(Com.PUSH, new Val(new Addr(r), t_val.GetSizeType()));
            }
            else if (t_val is Symbols.DOUBLE)
            {
                AddCode(Com.SUB, new Addr(Reg.ESP), new Val(8, size: 4));
                AddCode(Com.MOV, new Addr(Reg.ESP), new Val(new Addr(r), size: 8));
            }
        }
예제 #8
0
        private bool IsType(Token t)
        {
            switch (t.type)
            {
            case Token.Type.KW_STRUCT:
            case Token.Type.KW_ENUM:
                return(true);

            default:
                Symbols.Type tt = null;
                if (tstack.ContainsType(t.GetStrVal()))
                {
                    tt = tstack.GetType(t.GetStrVal());
                }
                return(tt != null && !(tt is Symbols.Func));
            }
        }
예제 #9
0
            public static BinaryConvertResult PostfixConvertResult(Expression lop, Expression rop,
                                                                   PostfixOperator op)
            {
                BinaryConvertResult res = new BinaryConvertResult();

                switch (op)
                {
                case PostfixOperator.REF:
                case PostfixOperator.DOT:
                    Symbols.Type t = lop.GetType() is Symbols.POINTER && op == PostfixOperator.REF?
                                     ((Symbols.POINTER)lop.GetType()).GetRefType() : lop.GetType();

                    if (!(t is Symbols.RECORD))
                    {
                        throw new Symbols.Exception(lop, NOT_STRUCT);
                    }

                    if (!((Symbols.RECORD)t).GetTable().ContainsVariable(((Identifier)rop).GetName()))
                    {
                        throw new Symbols.Exception(rop,
                                                    string.Format(NOT_MEMBER, ((Identifier)rop).GetName(), t.GetName())
                                                    );
                    }
                    res.lvalue = true;
                    res.type   = (((Symbols.RECORD)t).GetTable().GetVariable(((Identifier)rop).GetName())).GetType();
                    break;

                case PostfixOperator.INDEX:
                    if (!(lop.GetType() is Symbols.POINTER))
                    {
                        throw new Symbols.Exception(lop, NOT_POINTER);
                    }
                    if (!rop.GetType().IsInteger())
                    {
                        throw new Symbols.Exception(rop, NOT_INTEGER);
                    }
                    res.lvalue = true;
                    res.type   = ((Symbols.RefType)lop.GetType()).GetRefType();
                    break;
                }

                res.left  = lop;
                res.right = rop;
                return(res);
            }
예제 #10
0
 private void ParseTypedefs()
 {
     while (scan.Peek().type == Token.Type.KW_TYPEDEF)
     {
         Symbols.TYPEDEF typedef = new Symbols.TYPEDEF(scan.Read());
         Symbols.Type    type    = ParseTypeSpecifier();
         Pair <Symbols.Var, Pair <Symbols.RefType, Symbols.RefType> > pair = ParseDeclarator();
         if (pair.last != null)
         {
             pair.last.last.SetType(type);
             type = pair.last.first;
         }
         typedef.SetName(pair.first.GetName());
         typedef.SetType(type);
         tstack.AddSymbol(typedef);
         CheckToken(scan.Peek(), Token.Type.SEMICOLON, true);
     }
 }
예제 #11
0
파일: Parser.cs 프로젝트: Deliay/SuperBasic
        private Access Offset(Id a)
        {
            Expr i, t1, t2, loc;

            Symbols.Type type = a.Type;
            i = Bool();
            ExceptGrammar(Tag.RightBar);
            type = (type as Symbols.Array).Type;
            t1   = new Constant(type.Width);
            loc  = t1;
            while (Except(Tag.LeftBra))
            {
                i  = Bool(); ExceptGrammar(Tag.RightBar);
                t1 = new Constant(type.Width);
                t2 = new Arith(new Token('+', a.lexline, 0), loc, t1);
            }
            return(new Access(a, loc, type));
        }
예제 #12
0
파일: Parser.cs 프로젝트: Deliay/SuperBasic
        void dims(ref Symbols.Type p, Word name)
        {
            Number size = look as Number;

            if (ExceptGrammar(Tag.NUMBER))
            {
                if (ExceptGrammar(Tag.RightBar))
                {
                    if (Except(Tag.LeftBra))
                    {
                        dims(ref p, name);
                    }
                    p = new Symbols.Array(p, size.value);
                }
                else
                {
                    throw new TokenNotCloseArrayException(name);
                }
            }
        }
예제 #13
0
            public static void CheckCallFunction(Expression func, List <Expression> args)
            {
                Symbols.Type t = func.GetType();

                if (!(t is Symbols.Func || (t is Symbols.POINTER && ((Symbols.POINTER)t).GetRefType() is Symbols.Func)))
                {
                    throw new Symbols.Exception(func, NOT_FUNCTION);
                }

                Symbols.Func            f      = (Symbols.Func)(t is Symbols.Func ? t : ((Symbols.POINTER)t).GetRefType());
                List <Symbols.ParamVar> f_args = f.GetArguments();

                if (f_args.Count != args.Count && !f.IsUnspecifiedArgs())
                {
                    throw new Symbols.Exception(func, WRONG_NUMBER_ARGS);
                }

                for (int i = 0; i < f_args.Count; ++i)
                {
                    new Cast(args.ElementAt(i), f_args.ElementAt(i).GetType());
                }
            }
예제 #14
0
파일: Parser.cs 프로젝트: Deliay/SuperBasic
        private Params Params()
        {
            Symbols.Type type  = ReserveType.Void;
            List <Param> param = new List <Param>();

            ExceptGrammar(Tag.LeftPar);
            Token cur = look;

            while (Test(Tag.IDENTITY, Tag.OPTIONAL))
            {
                Param p = Param();
                param.Add(p);
                top.Add(p.ParamName.lexeme, new Id(p, top, 0, false));
            }
            ExceptGrammar(Tag.RightPar);
            if (Except(Tag.AS))
            {
                //just support reserve type
                type = look as Symbols.Type;
                ExceptGrammar(Tag.BASICTYPE);
            }

            return(new Params(cur.Line, param, type));
        }
예제 #15
0
 public Constant(Token tok, Symbols.Type p) : base(tok, p)
 {
 }
예제 #16
0
 public Temp(Symbols.Type p) : base(Word.Temp, p)
 {
     number = ++count;
 }
예제 #17
0
 public Op(Token tok, Symbols.Type p) : base(tok, p)
 {
 }
예제 #18
0
 public IdFunc(Function func, Word id, SymbolTable t, Symbols.Type p, int b, bool s) : base(id, t, p, b, s)
 {
     Func = func;
 }
예제 #19
0
 public RETURN(Symbols.Type ret_type)
 {
     this.ret_type = ret_type;
 }
예제 #20
0
            public static UnaryConvertResult ConvertUnaryOperand(Expression operand, Token op)
            {
                UnaryConvertResult res = new UnaryConvertResult();

                Symbols.Type t = operand.GetType();
                switch (op.type)
                {
                case Token.Type.OP_INC:
                case Token.Type.OP_DEC:
                    Token.Type tt = op.type == Token.Type.OP_DEC ?
                                    Token.Type.OP_SUB_ASSIGN : Token.Type.OP_PLUS_ASSIGN;

                    BinaryOperator bop = new BinaryOperator(new Token(tt));
                    bop.SetLeftOperand(operand);
                    bop.SetRightOperand(new Const("1", new Symbols.INT()));
                    res.type = bop.GetType();
                    break;

                case Token.Type.OP_BIT_AND:
                    if (!(operand.IsLvalue() || operand.GetType() is Symbols.Func))
                    {
                        throw new Symbols.Exception(operand, NOT_LVALUE_OR_FUNC);
                    }
                    res.type = new Symbols.POINTER(operand.GetType());
                    break;

                case Token.Type.OP_STAR:
                    res.lvalue = true;
                    if (!(t is Symbols.POINTER || t is Symbols.Func))
                    {
                        throw new Symbols.Exception(operand, NOT_POINTER);
                    }

                    if (t is Symbols.Func)
                    {
                        res.type = t;
                    }
                    else
                    {
                        res.type = ((Symbols.RefType)t).GetRefType();
                    }
                    break;

                case Token.Type.OP_PLUS:
                case Token.Type.OP_SUB:
                    if (!t.IsArifmetic())
                    {
                        throw new Symbols.Exception(operand, NOT_ARITHMETICAL);
                    }
                    res.type = t;
                    break;

                case Token.Type.OP_TILDE:
                    if (!t.IsInteger())
                    {
                        throw new Symbols.Exception(operand, NOT_INTEGER);
                    }
                    res.type = t;
                    break;

                case Token.Type.OP_NOT:
                    if (!(t.IsArifmetic() || t is Symbols.Func || t is Symbols.POINTER))
                    {
                        throw new Symbols.Exception(operand, string.Format(NO_OPERATOR, op.GetStrVal()));
                    }
                    res.type = new Symbols.INT();
                    break;

                case Token.Type.KW_SIZEOF:
                    res.type = new Symbols.INT();
                    break;

                case Token.Type.OP_DOT:
                default:
                    throw new System.NotImplementedException();
                }

                res.operand = operand;
                return(res);
            }
예제 #21
0
 public void SetTypeCast(Symbols.Type type)
 {
     this.type_cast = type;
     this.type = type;
     CheckOperands();
 }
예제 #22
0
 public static void CheckCast(Symbols.Type type, Symbols.Type cast_type)
 {
 }
예제 #23
0
파일: Errors.cs 프로젝트: Deliay/SuperBasic
 public TypeCovertException(int line, Symbols.Type T1, Symbols.Type T2) : base("Ln " + line + ", Type " + T1 + " cannot convert to " + T2)
 {
 }
예제 #24
0
파일: Errors.cs 프로젝트: Deliay/SuperBasic
 public TypeMisMatchException(int line, Symbols.Type T, string except) : base("Ln " + line + ", Type " + T + " not match covert rule (except: " + except.ToString() + ")")
 {
 }
예제 #25
0
        private void ParseDeclaration()
        {
            while (scan.Peek().type == Token.Type.SEMICOLON)
            {
                scan.Read();
            }
            if (scan.Peek().type == Token.Type.EOF)
            {
                return;
            }

            Token first_token = scan.Peek();
            Symbols.Type type = ParseTypeSpecifier(), variable_type = null;

            Pair<Symbols.Var, Pair<Symbols.RefType, Symbols.RefType>> pair = null;
            bool function = true;

            while (true)
            {
                variable_type = type;

                if ((pair = ParseDeclarator()) != null)
                {
                    if (pair.last != null)
                    {
                        pair.last.last.SetType(type);
                        variable_type = pair.last.first;
                    }

                    ///Когда мы устанавливаем финальный тип, то нужно пересчитать размер всех типов

                    if (pair.first == null && !(variable_type is Symbols.RECORD))
                    {
                        throw new Syntax.Exception("требуется идентификатор", scan.GetPos(), scan.GetLine());
                    }

                    if (pair.first != null)
                    {
                        pair.first.SetType(variable_type);
                    }

                    if (scan.Peek().type == Token.Type.OP_ASSIGN) // init declarator
                    {
                        Symbols.Var v = pair.first;
                        Syntax.Expression node = new Syntax.Identifier(
                            new Token(v.GetIndex(), v.GetLine(), Token.Type.IDENTIFICATOR, v.GetName()),
                            v
                        );
                        node = ParseBinaryOper(0, node, true);

                        //pair.first.SetInitializer(ParseInitializer());
                        pair.first.SetInitializer(node);
                        function = false;
                    }

                    if (function && scan.Peek().type == Token.Type.LBRACE && tstack.IsGlobal())
                    {
                        pair.last.first.SetName(pair.first.GetName());
                        tstack.AddSymbol(pair.first);
                        tstack.NewTable();

                        if (((Symbols.Func)pair.last.first).GetArguments()
                            .Count(x => x.GetName() == pair.first.GetName()) == 0)
                        {
                            tstack.AddSymbol(pair.first);
                        }

                        foreach (Symbols.Var arg in ((Symbols.Func)pair.last.first).GetArguments())
                        {
                            tstack.AddSymbol(arg);
                        }
                        this.ret_func_type = ((Symbols.Func)pair.last.first).GetRefType();
                        ((Symbols.Func)pair.last.first).SetBody(ParseCompound(false));
                        tstack.GetCurrentTable().RemoveSymbol(pair.first);
                        ((Symbols.Func)pair.last.first).SetTable(tstack.PopTable());
                    }
                    else
                    {
                        function = false;
                    }

                    if (!function && variable_type is Symbols.VOID)
                    {
                        throw new Symbols.Exception("недопустимо использование типа \"void\"",
                            first_token.GetIndex(), first_token.GetLine());
                    }

                    if (pair.first != null && !function)
                    {
                        try
                        {
                            tstack.AddSymbol(pair.first);
                        }
                        catch (Symbols.Exception e)
                        {
                            this.logger.Add(e);
                        }
                    }
                }

                if (scan.Peek().type != Token.Type.COMMA || function)
                {
                    break;
                }

                scan.Read();
                function = false;
            }

            if (!function)
            {
                CheckToken(scan.Peek(), Token.Type.SEMICOLON, true);
            }
        }
예제 #26
0
 public Access(Id a, Expr i, Symbols.Type p) : base(new Word(Tag.ARRAY, "[]", a.Op.Line, a.Op.Pos), p)
 {
     array = a;
     index = i;
 }
예제 #27
0
 public Expr(Token tok, Symbols.Type p) : base(tok.Line)
 {
     Op   = tok;
     Type = p;
 }
예제 #28
0
 void reserve(Symbols.Type t)
 {
     words.Add(t.lexeme, t);
 }
예제 #29
0
 public Param(Word name, Symbols.Type type) : base(name.Line)
 {
     ParamName = name;
     ParamType = type;
 }
예제 #30
0
파일: Parser.cs 프로젝트: Deliay/SuperBasic
        private Stmt stmt()
        {
            Expr x;
            Stmt s1, s2;
            Stmt saveStmt;

            if (Except(Tag.IF))
            {
                ExceptGrammar(Tag.LeftPar);
                x = Bool();
                ExceptGrammar(Tag.RightPar);
                s1 = stmt();

                if (!Except(Tag.ELSE))
                {
                    return(new If(x, s1));
                }
                s2 = stmt();
                return(new Else(x, s1, s2));
            }
            else if (Except(Tag.WHILE))
            {
                While node = new While(look.Line);
                saveStmt        = Stmt.Encloseing;
                Stmt.Encloseing = node;

                ExceptGrammar(Tag.LeftPar); x = Bool(); ExceptGrammar(Tag.RightPar);
                s1 = stmt();
                node.Init(x, s1);

                Stmt.Encloseing = saveStmt;
                return(node);
            }
            else if (Except(Tag.DO))
            {
                Do node = new Do(look.Line);
                saveStmt        = Stmt.Encloseing;
                Stmt.Encloseing = node;
                s1 = stmt();
                ExceptGrammar(Tag.WHILE); ExceptGrammar(Tag.LeftPar); x = Bool();
                ExceptGrammar(Tag.RightPar);

                node.Init(s1, x);

                Stmt.Encloseing = saveStmt;
                return(node);
            }
            else if (Except(Tag.DIM))
            {
                bool isStatic = Except(Tag.STATIC);
                Word curName  = look as Word;
                ExceptGrammar(Tag.IDENTITY);
                ExceptGrammar(Tag.AS);
                Symbols.Type type = look as Symbols.Type;
                ExceptGrammar(Tag.BASICTYPE);
                if (Except(Tag.LeftBra))
                {
                    // is array
                    dims(ref type, curName);
                }
                Id id = new Id(curName, top, type, used, isStatic);
                top.Add(curName.lexeme, id);
                used += type.Width;

                if (Except(Tag.Equal))
                {
                    //a init val
                    x = Bool();
                    return(new Set(id, x));
                }

                return(Stmt.Null);
            }
            else if (Except(Tag.RETURN))
            {
                Return ret;
                if (reader.ReadLast().TokenTag != Tag.LINE_END)
                {
                    ret = new Return(look.Line, Stmt.LastFunction as Function, Bool());
                    return(ret);
                }
                else
                {
                    move();
                    return(new Return(look.Line));
                }
            }
            else if (Except(Tag.BREAK))
            {
                return(new Break(look.Line));
            }
            else if (Except(Tag.CONTINUE))
            {
                return(new Continue(look.Line));
            }
            else if (Except(Tag.LeftBlock))
            {
                return(Block());
            }
            else
            {
                return(Assign());
            }
        }
예제 #31
0
 public void SetType(Symbols.Type type)
 {
     this.type = type;
 }
예제 #32
0
 public void Param(Param id, Symbols.Type t)
 {
     peekParam += t + " " + id + ",";
 }
예제 #33
0
            public static BinaryConvertResult ConvertBinaryOperands(Expression lop, Expression rop, Token op)
            {
                Symbols.Type        lt = lop.GetType(), rt = rop.GetType();
                BinaryConvertResult res = new BinaryConvertResult();

                res.op = op;
                Pair <Expression, Expression> uacon = null;

                switch (op.type)
                {
                case Token.Type.OP_STAR:
                case Token.Type.OP_DIV:
                    if (!lt.IsArifmetic())
                    {
                        throw new Symbols.Exception(lop, NOT_ARITHMETICAL);
                    }
                    if (!rt.IsArifmetic())
                    {
                        throw new Symbols.Exception(rop, NOT_ARITHMETICAL);
                    }

                    if (op.type == Token.Type.OP_MOD)
                    {
                        if (!lt.IsArifmetic())
                        {
                            lop = new Cast(lop, new Symbols.INT());
                        }
                        if (!rt.IsArifmetic())
                        {
                            rop = new Cast(rop, new Symbols.INT());
                        }
                        res.type = rop.GetType();
                        break;
                    }
                    uacon    = UsualArithmeticConversions(lop, rop);
                    lop      = uacon.first;
                    rop      = uacon.last;
                    res.type = lop.GetType();
                    break;

                case Token.Type.OP_MOD:
                    if (!lt.IsInteger())
                    {
                        throw new Symbols.Exception(lop, NOT_INTEGER);
                    }
                    if (!rt.IsInteger())
                    {
                        throw new Symbols.Exception(rop, NOT_INTEGER);
                    }

                    if (op.type == Token.Type.OP_MOD)
                    {
                        if (!(lt is Symbols.INT))
                        {
                            lop = new Cast(lop, new Symbols.INT());
                        }
                        if (!(rt is Symbols.INT))
                        {
                            rop = new Cast(rop, new Symbols.INT());
                        }
                        res.type = rop.GetType();
                        break;
                    }
                    uacon    = UsualArithmeticConversions(lop, rop);
                    lop      = uacon.first;
                    rop      = uacon.last;
                    res.type = lop.GetType();
                    break;

                case Token.Type.OP_PLUS:
                case Token.Type.OP_SUB:
                    if (rt is Symbols.POINTER || lt is Symbols.POINTER)
                    {
                        if (rt is Symbols.POINTER && lt is Symbols.POINTER)
                        {
                            if (op.type == Token.Type.OP_PLUS)
                            {
                                throw new Symbols.Exception(lop, NOT_ARITHMETICAL);
                            }
                            res.type = rt;
                            break;
                        }


                        BinaryOperator binop = new BinaryOperator(new Token(Token.Type.OP_STAR));
                        int            size  = 0;
                        if (rt is Symbols.POINTER)
                        {
                            lop = lt is Symbols.INT ? lop : new Cast(lop, new Symbols.INT());
                            binop.SetLeftOperand(lop);
                            size = ((Symbols.POINTER)rt).GetRefType().GetSizeType();
                            binop.SetRightOperand(new Const(size.ToString(), new Symbols.INT()));
                            lop      = binop;
                            res.type = rt;
                        }
                        else
                        {
                            rop = rt is Symbols.INT ? rop : new Cast(rop, new Symbols.INT());
                            binop.SetLeftOperand(rop);
                            size = ((Symbols.POINTER)lt).GetRefType().GetSizeType();
                            binop.SetRightOperand(new Const(size.ToString(), new Symbols.INT()));
                            rop      = binop;
                            res.type = lt;
                        }
                        break;
                    }

                    if (lt.IsArifmetic() || rt.IsArifmetic())
                    {
                        if (!lt.IsArifmetic())
                        {
                            throw new Symbols.Exception(lop, NOT_ARITHMETICAL);
                        }

                        if (!rt.IsArifmetic())
                        {
                            throw new Symbols.Exception(rop, NOT_ARITHMETICAL);
                        }

                        uacon    = UsualArithmeticConversions(lop, rop);
                        lop      = uacon.first;
                        rop      = uacon.last;
                        res.type = lop.GetType();
                        break;
                    }

                    if (lt is Symbols.Func ||
                        (lt is Symbols.POINTER && ((Symbols.POINTER)lt).GetRefType() is Symbols.Func))
                    {
                        throw new Symbols.Exception(lop, NOT_COMPLETE_TYPE);
                    }

                    if (rt is Symbols.Func ||
                        (rt is Symbols.POINTER && ((Symbols.POINTER)rt).GetRefType() is Symbols.Func))
                    {
                        throw new Symbols.Exception(rop, NOT_COMPLETE_TYPE);
                    }


                    throw new Symbols.Exception(lop, string.Format(NO_OPERATOR, op.GetStrVal()));

                case Token.Type.OP_L_SHIFT:
                case Token.Type.OP_R_SHIFT:
                case Token.Type.OP_BIT_AND:
                case Token.Type.OP_BIT_OR:
                case Token.Type.OP_XOR:
                    if (!lt.IsInteger())
                    {
                        throw new Symbols.Exception(lop, NOT_ARITHMETICAL);
                    }

                    if (!rt.IsInteger())
                    {
                        throw new Symbols.Exception(rop, NOT_ARITHMETICAL);
                    }
                    uacon    = UsualArithmeticConversions(lop, rop);
                    lop      = uacon.first;
                    rop      = uacon.last;
                    res.type = lop.GetType();
                    break;

                case Token.Type.OP_MORE:
                case Token.Type.OP_LESS:
                case Token.Type.OP_LESS_OR_EQUAL:
                case Token.Type.OP_MORE_OR_EQUAL:
                case Token.Type.OP_EQUAL:
                case Token.Type.OP_NOT_EQUAL:
                    uacon    = UsualArithmeticConversions(lop, rop);
                    lop      = uacon.first;
                    rop      = uacon.last;
                    res.type = lop.GetType();
                    break;

                case Token.Type.OP_AND:
                case Token.Type.OP_OR:
                    if (!(lt.IsArifmetic() || lt is Symbols.POINTER))
                    {
                        throw new Symbols.Exception(lop, string.Format(NO_OPERATOR, op.GetStrVal()));
                    }
                    if (!(rt.IsArifmetic() || rt is Symbols.POINTER))
                    {
                        throw new Symbols.Exception(rop, string.Format(NO_OPERATOR, op.GetStrVal()));
                    }
                    uacon    = UsualArithmeticConversions(lop, rop);
                    lop      = uacon.first;
                    rop      = uacon.last;
                    res.type = lop.GetType();
                    break;

                case Token.Type.OP_ASSIGN:
                    if (!lop.IsLvalue())
                    {
                        throw new Symbols.Exception(lop, NOT_LVALUE);
                    }


                    if (!lt.Equals(rt))
                    {
                        rop = new Cast(rop, lt);
                    }
                    res.type = lop.GetType();
                    break;

                case Token.Type.COMMA:
                    break;

                case Token.Type.OP_MUL_ASSIGN:
                case Token.Type.OP_DIV_ASSIGN:
                case Token.Type.OP_MOD_ASSIGN:
                case Token.Type.OP_PLUS_ASSIGN:
                case Token.Type.OP_SUB_ASSIGN:
                case Token.Type.OP_L_SHIFT_ASSIGN:
                case Token.Type.OP_R_SHIFT_ASSIGN:
                case Token.Type.OP_BIT_AND_ASSIGN:
                case Token.Type.OP_BIT_OR_ASSIGN:
                case Token.Type.OP_XOR_ASSIGN:
                    Token.Type tt = Token.Type.OP_STAR;
                    switch (op.type)
                    {
                    case Token.Type.OP_MUL_ASSIGN:
                        tt = Token.Type.OP_STAR;
                        break;

                    case Token.Type.OP_DIV_ASSIGN:
                        tt = Token.Type.OP_DIV;
                        break;

                    case Token.Type.OP_MOD_ASSIGN:
                        tt = Token.Type.OP_MOD;
                        break;

                    case Token.Type.OP_PLUS_ASSIGN:
                        tt = Token.Type.OP_PLUS;
                        break;

                    case Token.Type.OP_SUB_ASSIGN:
                        tt = Token.Type.OP_SUB;
                        break;

                    case Token.Type.OP_L_SHIFT_ASSIGN:
                        tt = Token.Type.OP_L_SHIFT;
                        break;

                    case Token.Type.OP_R_SHIFT_ASSIGN:
                        tt = Token.Type.OP_R_SHIFT;
                        break;

                    case Token.Type.OP_BIT_AND_ASSIGN:
                        tt = Token.Type.OP_BIT_AND;
                        break;

                    case Token.Type.OP_BIT_OR_ASSIGN:
                        tt = Token.Type.OP_BIT_OR;
                        break;

                    case Token.Type.OP_XOR_ASSIGN:
                        tt = Token.Type.OP_XOR;
                        break;
                    }
                    BinaryOperator bop = new BinaryOperator(new Token(tt));
                    bop.SetLeftOperand(lop);
                    bop.SetRightOperand(rop);
                    res.op = new Token(op.GetIndex(), op.GetLine(), Token.Type.OP_ASSIGN, "=");
                    BinaryOperator assign = new BinaryOperator(res.op);
                    assign.SetLeftOperand(lop);
                    assign.SetRightOperand(bop);
                    BinaryConvertResult r = ConvertBinaryOperands(lop, bop, res.op);
                    rop      = r.right;
                    lop      = r.left;
                    res.type = lop.GetType();
                    break;

                default:
                    throw new System.NotImplementedException();
                }

                res.left  = lop;
                res.right = rop;
                return(res);
            }
예제 #34
0
 public OptParam(Word name, Symbols.Type type, Constant defVal) : base(name, type)
 {
     DefaultValue = defVal;
 }