static void swap(ref IRList a, ref IRList b) { var _swp = a; a = b; b = _swp; }
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); }
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))); }
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))); }
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); }
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); }
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); }
/*########### * 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); }
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) }
public virtual IR subscript(IR i, IR subscript, IRList list) => null;
public virtual IR implicitCast(IR i, DataType to, IRList list) => null;
public virtual IR getMember(IR i, string name, IRList list) => null;
public virtual IR getMember(IR i, int index, IRList list) => null;