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; }
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(); } }
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); }
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()