예제 #1
0
        static void modifyType(AST_Node node)
        {
            AST_ModifyType mod = (AST_ModifyType)node;

            if (mod.target.result.dKind != ValueKind.STATIC_TYPE)
            {
                throw Jolly.addError(mod.target.location, "Not a type");
            }
            if ((mod.target.result.dType.flags & DataType.Flags.INSTANTIABLE) == 0)
            {
                throw Jolly.addError(mod.target.location, "The type {0} is not instantiable.".fill(mod.target.result.dType));
            }

            // TODO: Fix
            switch (mod.toType)
            {
            case AST_ModifyType.TO_SLICE:
            case AST_ModifyType.TO_ARRAY:
                mod.result = new IR {
                    irType = NT.BASETYPE, dType = new DataType_Array_Data(mod.target.result.dType), dKind = ValueKind.STATIC_TYPE
                };
                break;

            case AST_ModifyType.TO_POINTER:
            case AST_ModifyType.TO_NULLABLE:             // TODO: Make regular pointer non nullable
                mod.result = new IR {
                    irType = NT.BASETYPE, dType = new DataType_Reference(mod.target.result.dType), dKind = ValueKind.STATIC_TYPE
                };
                break;
            }

            DataType.makeUnique(ref mod.result.dType);
            mod.result.dKind = mod.target.result.dKind;
        }
예제 #2
0
        void parseBracketClose()
        {
            currentTokenKind = TokenKind.VALUE;

            Operator op;

            while ((op = operators.PopOrDefault()).operation != NT.BRACKET_OPEN)
            {
                if (op.operation == NT.UNDEFINED)
                {
                    throw Jolly.unexpected(token);
                }
                pushOperator(op);
            }

            Context context = contextStack.Pop();

            while (context.kind != Context.Kind.SUBSCRIPT)
            {
                contextEnd(context);
                context = contextStack.Pop();
            }

            if (context.hasColon)
            {
                var node = values.Peek();
                if (node.nodeType == NT.MODIFY_TYPE)
                {
                    ((AST_ModifyType)node).target = context.target;
                }
                else if (node.nodeType != NT.SLICE)
                {
                    throw Jolly.unexpected(node);
                }
            }
            else
            {
                AST_Node a = values.PopOrDefault();

                if (a == null)
                {
                    var mod = new AST_ModifyType(op.location, context.target, AST_ModifyType.TO_ARRAY);
                    ast.Add(mod);
                    values.Push(mod);
                    return;
                }
                var opNode = new AST_Operation(token.location, NT.SUBSCRIPT, a, null, false);
                values.Push(opNode);
                ast.Add(opNode);
            }

            if (values.Peek() == null)
            {
                values.Pop();
            }
        }
예제 #3
0
        void modifyType(byte toType)
        {
            AST_Node target = values.PopOrDefault();

            if (target == null)
            {
                throw Jolly.unexpected(token);
            }

            currentTokenKind = TokenKind.VALUE;
            var mod = new AST_ModifyType(token.location, target, toType);

            values.Push(mod);
            ast.Add(mod);
        }
예제 #4
0
        void pushOperator(Operator op)
        {
            AST_Node a, b = null;

            if (op.valCount == 2)
            {
                b = values.PopOrDefault();
                a = values.PopOrDefault();

                if (op.operation == NT.COMMA)
                {
                    if (a == null)
                    {
                        values.Push(null);
                        if (!(b is AST_Tuple))
                        {
                            var tup = new AST_Tuple(b.location, NT.TUPLE);
                            tup.values.Add(b);
                            values.Push(tup);
                            return;
                        }
                        values.Push(b);
                        return;
                    }

                    AST_Tuple tuple = a as AST_Tuple;
                    if (tuple?.closed ?? true)
                    {
                        tuple = new AST_Tuple(b.location, NT.TUPLE);
                        tuple.values.Add(a);
                    }
                    tuple.values.Add(b);
                    values.Push(tuple);
                    return;
                }
                else if (op.operation == NT.SLICE)
                {
                    if (a == null & b == null)
                    {
                        var mod = new AST_ModifyType(op.location, null, AST_ModifyType.TO_SLICE);
                        values.Push(mod);
                        ast.Add(mod);
                        return;
                    }
                    // Slice allows a value to be null
                    var slice = (a == null) ?
                                new AST_Operation(op.location, NT.SLICE, b, null, true) :
                                new AST_Operation(op.location, NT.SLICE, a, b, true);
                    values.Push(slice);
                    ast.Add(slice);
                    return;
                }

                if (a == null)
                {
                    throw Jolly.addError(op.location, "Expecting 2 values");
                }
                if (op.operation == NT.GET_MEMBER && b.nodeType == NT.NAME)
                {
                    b.nodeType = NT.MEMBER_NAME;
                }
            }
            else
            {
                a = values.PopOrDefault();
                if (a == null)
                {
                    throw Jolly.addError(op.location, "Invalid expression term");
                }
            }

            if (op.isSpecial)
            {
                if (op.operation == NT.LOGIC_AND)
                {
                    int memberCount = ast.Count - op.operatorIndex;
                    var logic       = new AST_Logic(op.location, NT.LOGIC_OR, memberCount, memberCount, condition: a, a: b, b: null);
                    values.Push(logic);
                    ast.Insert(op.operatorIndex, logic);
                    return;
                }
                else if (op.operation == NT.LOGIC_OR)
                {
                    int memberCount = ast.Count - op.operatorIndex;
                    var logic       = new AST_Logic(op.location, NT.LOGIC_AND, memberCount, memberCount, condition: a, a: b, b: null);
                    values.Push(logic);
                    ast.Insert(op.operatorIndex, logic);
                    return;
                }
                else if (op.operation == NT.TERNARY)
                {
                    Context context = contextStack.Pop();
                    while (context.kind != Context.Kind.TERNARY)
                    {
                        contextEnd(context);
                        context = contextStack.Pop();
                    }
                    context.target = a;
                    contextStack.Push(context);
                    values.Push(b);
                    return;
                }
                else if (op.operation == NT.TERNARY_SELECT)
                {
                    Context context = contextStack.Pop();
                    while (context.kind != Context.Kind.TERNARY)
                    {
                        contextEnd(context);
                        context = contextStack.Pop();
                    }

                    int memberCount = ast.Count - context.index,
                        count       = op.operatorIndex - context.index;
                    var logic       = new AST_Logic(op.location, NT.TERNARY, memberCount, count, context.target, a, b);
                    values.Push(logic);
                    ast.Insert(context.index, logic);
                    return;
                }
                Jolly.addNote(op.location, "Compiler: unnecessary operator marked special {0}".fill(op.operation));
            }     // if(op.isSpecial)

            AST_Operation opNode = new AST_Operation(op.location, op.operation, a, b, op.leftToRight);

            values.Push(opNode);
            ast.Add(opNode);
        } // pushOperator()