Beispiel #1
0
        static void swap(ref IRList a, ref IRList b)
        {
            var _swp = a;

            a = b;
            b = _swp;
        }
Beispiel #2
0
        public static IRList analyse(List <AST_Node> program, SymbolTable globalScope)
        {
            Analyser.program = program;
            instructions     = new IRList();
            contextStack     = new ContextStack(16);
            enclosureStack   = new EnclosureStack(16);

            contextStack.Push(new Context(int.MaxValue, Context.Kind.STATEMENT));     // Just put something on the stack
            enclosureStack.Push(new Enclosure(NT.GLOBAL, null, globalScope, int.MaxValue));

            program.forEach((n, i) => Console.WriteLine("{0}: {1}".fill(i, n)));
            Console.WriteLine();

            for (cursor = 0; cursor < program.Count; incrementCursor(ref cursor))
            {
                Action <AST_Node> action;
                AST_Node          node = program[cursor];
                if (typeDefinitionAnalysers.TryGetValue(node.nodeType, out action))
                {
                    action(node);
                }
            }

            isDefineFase = false;

            for (cursor = 0; cursor < program.Count; incrementCursor(ref cursor))
            {
                analyseNode(program[cursor]);
            }

            return(instructions);
        }
Beispiel #3
0
 public override IR getMember(IR i, int index, IRList list)
 {
     if (index >= members.Length)
     {
         throw Jolly.addError(new SourceLocation(), "Out of index bounds");
     }
     return(list.Add(IR.getMember(i, members[index], index)));
 }
Beispiel #4
0
 public override IR subscript(IR i, IR index, IRList list)
 {
     if (index.dType != Lookup.I32)
     {
         throw Jolly.addError(new SourceLocation(), "Only int can be used as subscript");
     }
     return(list.Add(IR.operation <IR_Substript>(i, index, null)));
 }
Beispiel #5
0
        static bool inferAutoVariable(AST_Node i, AST_Node other, IRList instructions)
        {
            DataType type        = other.result.dType;
            var      declaration = (AST_Declaration)i;

            // Has to be instantiable and not unfinished
            if ((type.flags & (DataType.Flags.INSTANTIABLE | DataType.Flags.UNFINISHED)) != DataType.Flags.INSTANTIABLE)
            {
                throw Jolly.addError(declaration.location, "The inferred type {0} is not instantiable.".fill(type));
            }
            declaration.symbol.declaration.dType = type;
            return(true);
        }
Beispiel #6
0
        public override IR implicitCast(IR i, DataType to, IRList list)
        {
            if (!(to is DataType_Reference))
            {
                return(null);
            }
            DataType_Struct iterator = this;

            while (iterator != null)
            {
                if (iterator == to)
                {
                    return(list.Add(IR.cast <IR_Reinterpret>(i, to, null)));
                }
            }
            return(null);
        }
Beispiel #7
0
        public override IR getMember(IR i, string name, IRList list)
        {
            int             index;
            DataType_Struct iterator = this;

            while (iterator != null)
            {
                if (iterator.memberMap.TryGetValue(name, out index))
                {
                    IR _struct = i;
                    if (iterator != this)
                    {
                        _struct = list.Add(IR.cast <IR_Reinterpret>(i, iterator, null));
                    }
                    return(list.Add(IR.getMember(_struct, iterator.members[index], index + (iterator.inherits == null ? 0 : 1))));
                }
                iterator = iterator.inherits;
            }
            return(null);
        }
Beispiel #8
0
        /*###########
        *   Hooks
        ###########*/

        static bool inferObject(AST_Node i, AST_Node other, IRList instructions)
        {
            var _object   = (AST_Object)i;
            var inferFrom = _object.inferFrom?.result ?? other.result;
            var errLoc    = _object.inferFrom?.location ?? other.location;

            if ((inferFrom.dType.flags & DataType.Flags.INSTANTIABLE) == 0)
            {
                throw Jolly.addError(errLoc, "Cannot instantiate auto");
            }
            // TODO: Add further type checks

            int end = _object.startIndex + _object.memberCount;

            _object.result.dType = inferFrom.dType;
            enclosureStack.Push(new Enclosure(NT.OBJECT, _object, enclosure.scope, end));
            for (int j = _object.startIndex; j < end; incrementCursor(ref j))
            {
                analyseNode(program[j]);
            }
            return(true);
        }
Beispiel #9
0
        static void contextEnd(Context ended)
        {
            switch (ended.kind)
            {
            case Context.Kind.TUPLE: {
                AST_Tuple      tuple = (AST_Tuple)ended.target;
                DataType_Tuple tupleType;
                ValueKind      tupleKind;
                getTuple_Type_Kind(tuple, out tupleType, out tupleKind);

                // If the tuple doesn't contain names pack it
                if ((tupleKind & (ValueKind.ADDRES | ValueKind.STATIC_TYPE)) == 0)
                {
                    tuple.result = instructions.Add(new IR_Read {
                            target = packTuple(tuple, tupleType), dType = tupleType
                        });
                }
                else
                {
                    tuple.result = new IR {
                        irType = NT.TUPLE, dType = tupleType, dKind = tupleKind
                    };
                }
            } break;

            case Context.Kind.IF_CONDITION: {
                var ifNode = (AST_If)ended.target;
                load(ifNode.condition);
                implicitCast(ref ifNode.condition.result, Lookup.I1);
                ifNode.result = instructions.Add(new IR_If {
                        condition = ifNode.condition.result, ifBlock = instructions
                    });
                contextStack.Push(new Context(cursor + ifNode.ifCount, Context.Kind.IF_TRUE)
                    {
                        target = ifNode
                    });
                instructions = new IRList();
            } break;

            case Context.Kind.IF_TRUE: {
                var ifNode = (AST_If)ended.target;
                var ifIR   = (IR_If)ifNode.result;
                swap(ref instructions, ref ifIR.ifBlock);

                if (ifNode.elseCount > 0)
                {
                    ifIR.elseBlock = instructions;
                    instructions   = new IRList();
                    contextStack.Push(new Context(cursor + ifNode.elseCount, Context.Kind.IF_FALSE)
                        {
                            target = ifNode
                        });
                }
            } break;

            case Context.Kind.IF_FALSE: {
                var ifNode = (AST_If)ended.target;
                var ifIR   = (IR_If)ifNode.result;
                swap(ref instructions, ref ifIR.elseBlock);
            } break;

            case Context.Kind.LOGIC_OR: {
                var lor   = (AST_Logic)ended.target;
                var lorIR = (IR_Logic)lor.result;
                load(lor.a);
                implicitCast(ref lor.a.result, Lookup.I1);
                swap(ref instructions, ref lorIR.block);
                lorIR.a = lor.a.result;
            } break;

            case Context.Kind.LOGIC_AND: {
                var land   = (AST_Logic)ended.target;
                var landIR = (IR_Logic)land.result;
                load(land.a);
                implicitCast(ref land.a.result, Lookup.I1);
                swap(ref instructions, ref landIR.block);
                landIR.a = land.a.result;
            } break;

            case Context.Kind.DECLARATION: {
                // type inference
                var declaration = (AST_Declaration)ended.target;
                var alloc       = (IR_Allocate)declaration.result;

                if (alloc.dType == Lookup.AUTO || !alloc.initialized)
                {
                    throw Jolly.addError(declaration.location, "Auto variables must be initialized.");
                }
            } break;

            case Context.Kind.FUNCTION_DECLARATION: {
                // The declaration ends after the return values and arguments are parsed.
                var function     = (AST_Function)enclosure.node;
                var functionType = (DataType_Function)function.result.dType;
                functionType.returns = function.returns.result.dType;
                DataType.makeUnique(ref function.result.dType);
                cursor = enclosure.end; // Skip to end of function enclosure
            } break;
            }                           // switch(ended.kind)
        }
Beispiel #10
0
 public virtual IR subscript(IR i, IR subscript, IRList list) => null;
Beispiel #11
0
 public virtual IR implicitCast(IR i, DataType to, IRList list) => null;
Beispiel #12
0
 public virtual IR getMember(IR i, string name, IRList list) => null;
Beispiel #13
0
 public virtual IR getMember(IR i, int index, IRList list) => null;