public static TYPE parseTypeSpecifier(iSCOPE context, out bool ref_val, out bool conc, out Span final) { TYPE type = null; bool opt = false; ref_val = false; conc = false; Token token = get(); Token begin = token; if (token.code == TokenCode.Question) { forget(); token = get(); opt = true; } switch (token.code) { case TokenCode.As: forget(); EXPRESSION example = PRIMARY.parse(null, context); type = example.type; if (type != null) { type.setSpan(begin.span, example.span); if (type is UNIT_REF) { (type as UNIT_REF).setSpecs(opt, true); } } final = example.span; break; case TokenCode.Ref: ref_val = true; forget(); goto ParseType; case TokenCode.Concurrent: conc = true; forget(); goto ParseType; case TokenCode.Val: forget(); goto ParseType; case TokenCode.LParen: // Seems to a tuple type type = TUPLE_TYPE.parse(context); context.add(type); final = type.span; break; default: // forget(); ParseType: UNIT_REF unitRef = UNIT_REF.parse(null, opt, context); if (unitRef == null) /* An error was detected earlier */ { final = null; return(null); } final = unitRef.span; token = get(); return(unitRef); } return(type); }
public static TYPE parse(iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering TYPE.parse"); Token token = get(); TYPE result = null; switch (token.code) { case TokenCode.LParen: result = TUPLE_TYPE.parse(context); break; case TokenCode.Routine: result = ROUTINE_TYPE.parse(context); break; case TokenCode.Identifier: { // Don't forget() UNIT_REF unit_type = UNIT_REF.parse(null, false, context); Token del = get(); if (del.code == TokenCode.Vertical) { // Don't call forget() result = MULTI_TYPE.parse(unit_type, context); } else { result = unit_type; } break; } default: // Syntax error { break; } } Debug.WriteLine("Exiting TYPE.parse"); Debug.Unindent(); return(result); }
/// <summary> /// /// </summary> /// <returns></returns> public static FORMAL_TYPE parse(Token id, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering FORMAL_TYPE.parse"); // Identifier was parsed before and is passed via 'id'. FORMAL_TYPE generic_type_par = new FORMAL_TYPE(id); Token token = get(); if (token.code != TokenCode.Arrow2) { goto Finish; } // -> TYPE base_type = null; forget(); token = get(); if (token.code == TokenCode.Identifier) { forget(); base_type = UNIT_REF.parse(token, false, context); } else if (token.code == TokenCode.LParen) // T->(tuple) { base_type = TUPLE_TYPE.parse(context); } else { // Syntax error } generic_type_par.base_type = base_type; token = get(); if (token.code != TokenCode.Init) { goto Finish; } forget(); token = get(); // init if (token.code != TokenCode.LParen) { goto Finish; } forget(); token = get(); if (token.code == TokenCode.RParen) { forget(); goto Finish; } while (true) { TYPE init_param_type = TYPE.parse(context); generic_type_par.add(init_param_type); init_param_type.parent = generic_type_par; token = get(); if (token.code == TokenCode.Comma) { forget(); continue; } break; } token = expect(TokenCode.RParen); Finish: Debug.WriteLine("Exiting FORMAL_TYPE.parse"); Debug.Unindent(); generic_type_par.setSpan(id, token); return(generic_type_par); }
/// <summary> /// /// </summary> /// <syntax> /// UnitTypeName : CompoundName [ GenericInstantiation ] /// /// GenericInstantiation : "[" (Type|Expression) { "," (Type|Expression) } "]" /// </syntax> /// <returns></returns> public static UNIT_REF parse(Token id, bool opt, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering UNIT_REF.parse"); Token token = null; // We assume that 'id' is 'identifier'. if (id == null) { token = get(); forget(); } else { token = id; } token = IDENTIFIER.parseCompoundName(token); if (token == null) /* an error was detected earlier */ return { (null); } Token start = token; UNIT_REF unit_ref = new UNIT_REF(token.image); unit_ref.opt = opt; unit_ref.as_sign = true; DECLARATION unit = Context.find(token); if (unit != null && (unit is UNIT || unit is FORMAL_TYPE)) { unit_ref.unit_ref = unit; } token = get(); if (token.code == TokenCode.LBracket) { forget(); while (true) { TYPE type = null; token = get(); if (token.code == TokenCode.LParen) { type = TUPLE_TYPE.parse(context); unit_ref.add(type); goto Delimiter; } EXPRESSION expr = EXPRESSION.parse(null, context); if (expr is REFERENCE || expr is UNRESOLVED) { string name = null; if (expr is REFERENCE) { if ((expr as REFERENCE).declaration is UNIT) { name = (expr as REFERENCE).declaration.name.identifier; } else { goto NonType; } } else // UNRESOLVED { name = (expr as UNRESOLVED).name.identifier; } id = new Token(expr.span, TokenCode.Identifier, name, new Category(CategoryCode.identifier)); type = UNIT_REF.parse(id, false, context); // Recursive call unit_ref.add(type); type.parent = unit_ref; goto Delimiter; } // else -- expr is perhaps a non-type argument NonType: token = get(); if (token.code == TokenCode.DotDot) { // This is actually a range _type_ forget(); EXPRESSION right = EXPRESSION.parse(null, context); RANGE_TYPE range = new RANGE_TYPE(expr, right); range.setSpan(expr.span, right.span); unit_ref.add(range); range.parent = unit_ref; } else // Definitely a non-type argument { unit_ref.add(expr); expr.parent = unit_ref; } Delimiter: token = get(); switch (token.code) { case TokenCode.Comma: forget(); continue; case TokenCode.RBracket: forget(); goto Finish; default: { /* Syntax error in generic actuals */ break; } } } Finish: unit_ref.setSpan(start.span, token.span); } else { unit_ref.setSpan(start); } Debug.WriteLine("Exiting UNIT_REF.parse"); Debug.Unindent(); return(unit_ref); }