public static MULTI_TYPE parse(UNIT_REF first, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering MULTI_TYPE.parse"); MULTI_TYPE multi = new MULTI_TYPE(); multi.add(first); Span begin = first.span; UNIT_REF elem_type = null; while (true) { Token token = get(); if (token.code != TokenCode.Vertical) { break; } forget(); elem_type = UNIT_REF.parse(null, false, context); multi.add(elem_type); } multi.setSpan(begin, elem_type.span); Debug.WriteLine("Exiting MULTI_TYPE.parse"); Debug.Unindent(); return(multi); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result; Token token = (first != null) ? first : get(); switch (token.code) { case TokenCode.Plus: case TokenCode.Minus: case TokenCode.Tilde: forget(); EXPRESSION second = UNARY.parse(null, context); result = new UNARY(token, second); result.setSpan(token.span, second.span); break; case TokenCode.New: forget(); UNIT_REF unitRef = UNIT_REF.parse(null, false, context); result = new NEW(unitRef); result.setSpan(token.span, unitRef.span); break; default: result = POWER.parse(token, context); break; } return(result); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = UNARY.parse(first, context); while (true) { Token token = get(); switch (token.code) { case TokenCode.Multiply: case TokenCode.Divide: case TokenCode.Remainder: forget(); break; default: goto Out; } EXPRESSION second = UNARY.parse(null, context); Span begin = result.span; result = new MULTIPLICATIVE(token, result, second); result.setSpan(begin, second.span); } Out: return(result); }
public static new FORMAL_GENERIC parse(iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering FORMAL_GENERIC.parse"); Token id = expect(TokenCode.Identifier); if (id == null) { return(null); // error } FORMAL_GENERIC result = null; Token token = get(); if (token.code == TokenCode.Colon) { forget(); result = FORMAL_NONTYPE.parse(id, context); } else { result = FORMAL_TYPE.parse(id, context); } Debug.WriteLine("Exiting FORMAL_GENERIC.parse"); Debug.Unindent(); return(result); }
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 iSCOPE currentScope { get; private set; } public static void enter(iSCOPE scope) { display[currentLevel] = scope; currentLevel++; // scope.enclosing = currentScope; // currentScope = scope; }
public static EXPRESSION parse(iSCOPE context) { Token token = get(); forget(); Span begin = token.span; CONDITIONAL result = new CONDITIONAL(); EXPRESSION elsePart = null; EXPRESSION condition = EXPRESSION.parse(null, context); expect(TokenCode.Then); EXPRESSION thenPart = EXPRESSION.parse(null, context); COND_IF_THEN cit = new COND_IF_THEN(condition, thenPart); condition.parent = result; thenPart.parent = result; cit.parent = result; result.add(cit); token = get(); while (true) { if (token.code == TokenCode.Elsif) { forget(); condition = EXPRESSION.parse(null, context); expect(TokenCode.Then); thenPart = EXPRESSION.parse(null, context); cit = new COND_IF_THEN(condition, thenPart); cit.setSpan(token.span, thenPart.span); condition.parent = result; thenPart.parent = result; cit.parent = result; result.add(cit); token = get(); // go to next iteration } else { break; } } token = expect(TokenCode.Else); elsePart = EXPRESSION.parse(null, context); elsePart.parent = result; result.add(elsePart); result.setSpan(begin, elsePart.span); // context.add(result); ?? why ?? return(result); }
/// <summary> /// /// </summary> /// <returns></returns> public static void parse(bool hidden, bool final, Token start, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering CONSTANT.parse"); CONSTANT constant = new CONSTANT(); // 'const' and 'is' keywords were already parsed Token token = get(); if (token.code == TokenCode.End) { forget(); goto FinalActions; } // empty list while (true) { EXPRESSION left = EXPRESSION.parse(null, context); token = get(); if (token.code == TokenCode.DotDot) // range { forget(); EXPRESSION right = EXPRESSION.parse(null, context); BINARY range = new BINARY(left, right); range.setSpan(left.span, right.span); range.parent = constant; constant.constants.Add(range); } else // single expression { left.parent = constant; constant.constants.Add(left); } token = get(); if (token.code == TokenCode.Comma) { forget(); continue; } if (token.code == TokenCode.End) { forget(); break; } else { error(token, "syntax-error"); break; } } FinalActions: constant.setSpecs(hidden, final); context.add(constant); constant.parent = context.self; constant.setSpan(start, token); Debug.WriteLine("Exiting CONSTANT.parse"); Debug.Unindent(); }
new public static ROUTINE_TYPE parse(iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering ROUTINE_TYPE.parse"); Debug.WriteLine("Exiting ROUTINE_TYPE.parse"); Debug.Unindent(); return(null); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = ADDITIVE.parse(first, context); Token token = get(); switch (token.code) { case TokenCode.Less: case TokenCode.LessEqual: case TokenCode.Greater: case TokenCode.GreaterEqual: case TokenCode.Equal: case TokenCode.NotEqual: case TokenCode.EqualEqual: case TokenCode.NotEqualDeep: forget(); break; case TokenCode.In: forget(); EXPRESSION left = EXPRESSION.parse(null, context); token = get(); if (token.code == TokenCode.DotDot) { forget(); EXPRESSION right = EXPRESSION.parse(null, context); RANGE_TYPE range = new RANGE_TYPE(left, right); range.setSpan(left.span, right.span); Span start = result.span; IN_EXPRESSION r = new IN_EXPRESSION(token, result, range); result.parent = r; result = r; result.setSpan(start, range.span); goto Out; } else { // Something's wrong: right part of the in-expression // should always be a range-type goto Out; } default: goto Out; } EXPRESSION second = ADDITIVE.parse(null, context); Span start2 = result.span; result = new RELATIONAL(token, result, second); result.setSpan(start2, second.span); Out: return(result); }
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> /// <syntax> /// Try : try /// StatementList /// catch ( [ Identifier : ] UnitType ) /// [ StatementList ] /// { catch ( [ Identifier : ] UnitType ) /// [ StatementList ] /// } /// [ else [ StatementsList ] ] /// end /// </syntax> /// <returns></returns> public static void parse(iSCOPE context) { Token token = get(); Token begin = token; if (token.code != TokenCode.Try) // Compiler error { } forget(); TRY result = new TRY(); Context.enter(result); BODY.parse(TokenCode.Catch, TokenCode.ERROR, TokenCode.ERROR, result); while (true) { token = get(); if (token.code != TokenCode.Catch) { break; } CATCH.parse(result); } token = get(); if (token.code == TokenCode.Else) { forget(); BODY.parse(TokenCode.End, TokenCode.ERROR, TokenCode.ERROR, context); } token = get(); if (token.code != TokenCode.End) // Syntax error { } forget(); result.setSpan(begin, token); context.add(result); Context.exit(); }
public static FORMAL_NONTYPE parse(Token id, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering FORMAL_NONTYPE.parse"); // parameter name is passed via 'id'. // ':' is already eaten. FORMAL_NONTYPE generic_nontype_par = new FORMAL_NONTYPE(id); TYPE type = TYPE.parse(context); generic_nontype_par.type = type; type.parent = generic_nontype_par; Debug.WriteLine("Exiting FORMAL_NONTYPE.parse"); Debug.Unindent(); generic_nontype_par.setSpan(id.span, type.span); return(generic_nontype_par); }
public static CALL parse(EXPRESSION reference, iSCOPE context) { CALL call = new CALL(reference); Token token; while (true) { EXPRESSION arg = EXPRESSION.parse(null, context); call.add(arg); token = get(); if (token.code == TokenCode.Comma) { forget(); continue; } break; } token = expect(TokenCode.RParen); call.setSpan(reference.span, token.span); return(call); }
public static void parse(iSCOPE context) { bool useConst = false; Token token = get(); Token begin = token; if (token.code == TokenCode.Const) { forget(); useConst = true; } while (true) { UNIT_REF ur = UNIT_REF.parse(null, false, context); USE result = new USE(ur, useConst); result.parent = context.self; result.setSpan(begin.span, ur.span); if (context is UNIT) { (context as UNIT).add(result); } else if (context is COMPILATION) { (context as COMPILATION).add(result); } // else // -- Some other use of 'use' token = get(); if (token.code != TokenCode.Comma) { break; } forget(); } }
public static new EXPRESSION parse(Token token, iSCOPE context) { EXPRESSION result = SECONDARY.parse(token, context); while (true) { token = get(); if (token.code == TokenCode.Power) { forget(); EXPRESSION right = UNARY.parse(null, context); Span begin = result.span; result = new POWER(result, right); result.setSpan(begin, right.span); } else { goto Out; } } Out: return(result); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = MULTIPLICATIVE.parse(first, context); while (true) { Token token = get(); switch (token.code) { case TokenCode.Plus: case TokenCode.Minus: forget(); break; default: goto Out; } EXPRESSION second = MULTIPLICATIVE.parse(null, context); Span start = result.span; result = new ADDITIVE(token, result, second); result.setSpan(start, second.span); } Out: return(result); }
/// <summary> /// /// </summary> /// <syntax> /// Объявление-контейнера /// : [ Спецификатор-контейнера ] unit Имя-контейнера [ FormalGenerics ] /// { Директива-контейнера } /// is /// Тело-контейнера /// [ invariant Список-предикатов ] /// end /// /// Спецификатор-контейнера /// : ref | val | concurrent | abstract /// /// Имя-контейнера /// : Составное-имя /// /// Директива-контейнера /// : Директива-наследования /// | Директива-использования /// /// Директива-наследования /// : extend Базовый-контейнер { , Базовый-контейнер } /// /// Базовый-контейнер /// : [ ~ ] UnitTypeName /// /// Тело-контейнера /// : { Объявление } /// </syntax> /// <returns></returns> public static void parse(bool hidden, bool final, bool abstr, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering UNIT.parse"); bool ref_val = false; // unit is reference by default bool concurrent = false; UNIT unit = null; Token token = get(); Token begin = token; TokenCode code = TokenCode.Unit; switch (token.code) { case TokenCode.Ref: ref_val = true; forget(); code = getUnitKeyword(); break; case TokenCode.Val: ref_val = false; forget(); code = getUnitKeyword(); break; case TokenCode.Abstract: abstr = true; forget(); code = getUnitKeyword(); break; case TokenCode.Concurrent: concurrent = true; forget(); code = getUnitKeyword(); break; case TokenCode.Unit: code = TokenCode.Unit; forget(); break; case TokenCode.Package: code = TokenCode.Package; forget(); break; } // 1. Unit header token = expect(TokenCode.Identifier); Token compoundName = IDENTIFIER.parseCompoundName(token); if (code == TokenCode.Package) { if (!ENTITY.options.optConfig) { warning(token, "no-config"); unit = new UNIT(compoundName.image, ref_val, abstr, concurrent); } else { unit = new PACKAGE(compoundName.image, ref_val, abstr, concurrent); } } else { unit = new UNIT(compoundName.image, ref_val, abstr, concurrent); } Debug.WriteLine("======================" + compoundName.image); unit.parent = context.self; unit.setSpecs(hidden, final); Context.enter(unit); // 2. Generic parameters token = get(); if (token.code == TokenCode.LBracket) { forget(); while (true) { var generic = FORMAL_GENERIC.parse(unit); unit.add(generic); token = get(); switch (token.code) { case TokenCode.Comma: case TokenCode.Semicolon: forget(); continue; case TokenCode.RBracket: forget(); goto Finish; default: { /* Syntax error */ break; } } } Finish: ; } // Possible unit alias token = get(); if (token.code == TokenCode.Alias) { forget(); token = expect(TokenCode.Identifier); unit.alias = new IDENTIFIER(token); } // 3. Unit directives: inheritance token = get(); if (token.code == TokenCode.Extend) { forget(); while (true) { PARENT parent = PARENT.parse(unit); if (parent == null) /* Syntax error */ break { ; } unit.add(parent); token = get(); switch (token.code) { case TokenCode.Comma: case TokenCode.Semicolon: case TokenCode.EOL: forget(); continue; default: goto Use; } } }
public static void parse(TokenCode stop1, TokenCode stop2, TokenCode stop3, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering BODY.parse"); Token token; Token start = get(); while (true) { bool res = STATEMENT.parse(context, stop1, stop2, stop3); if (!res) { // Neither a statement nor a simple declaration. // Perhaps, a nested/local function? token = get(); switch (token.code) { case TokenCode.Routine: case TokenCode.Safe: case TokenCode.Pure: forget(); int pure_safe = 0; switch (token.code) { case TokenCode.Pure: pure_safe = 1; break; case TokenCode.Safe: pure_safe = 2; break; } ROUTINE.parse(null, false, false, false, pure_safe, context); break; case TokenCode.Unit: case TokenCode.Ref: case TokenCode.Val: // A _local_ unit??? UNIT.parse(context); break; default: // What's this? break; } } token = get(); if (token.code == TokenCode.Semicolon /*|| wasEOL*/) { forget(); } if (token.code == stop1) { break; // don't 'forget()' } if (stop2 != TokenCode.ERROR && token.code == stop2) { break; // don't 'forget()' } if (stop3 != TokenCode.ERROR && token.code == stop3) { break; // don't 'forget()' } } BODY body = context as BODY; if (body == null) /* A system error */ } {
/// <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); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = PRIMARY.parse(first, context); if (result == null) { return(null); } Span begin = result.span; while (true) { Token token = get(); switch (token.code) { case TokenCode.Dot: forget(); IDENTIFIER identifier; token = get(); if (token.code == TokenCode.Init) { forget(); // Initializer call in full form identifier = new IDENTIFIER(INITIALIZER.initName); } else if (token.code == TokenCode.Identifier) { forget(); identifier = new IDENTIFIER(token); } else // syntax error { identifier = new IDENTIFIER("ERROR"); } result = new MEMBER(result, identifier); result.setSpan(begin, token.span); break; case TokenCode.LParen: forget(); result = new CALL(result); while (true) { token = get(); if (token.code == TokenCode.RParen) { forget(); break; } EXPRESSION actual = EXPRESSION.parse(null, context); (result as CALL).add(actual); token = get(); if (token.code == TokenCode.Comma) { forget(); continue; } token = expect(TokenCode.RParen); break; } result.setSpan(begin, token.span); break; default: goto Out; } } Out: return(result); }
/// <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); }
/// <summary> /// /// </summary> /// <returns></returns> new public static TUPLE_TYPE parse(iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering TUPLE_TYPE.parse"); TUPLE_TYPE tuple = new TUPLE_TYPE(); Token begin = expect(TokenCode.LParen); int count = 0; Token token = get(); if (token.code == TokenCode.RParen) { // Empty tuple forget(); goto OutLoop; } var ids = new List <Token>(); UNIT_REF unit_type; while (true) { token = expect(TokenCode.Identifier); Token delimiter = get(); switch (delimiter.code) { case TokenCode.Comma: // Identifier is the current name in the list of fields forget(); ids.Add(token); continue; case TokenCode.Colon: // Identifier is the last name in the field of fields forget(); ids.Add(token); // Now we treat collected ids as names of tuple fields, // and the construct following ':' as unit name. unit_type = UNIT_REF.parse(null, false, context); unit_type.parent = tuple; foreach (Token id in ids) { if (tuple.exists(id.image)) // Error: duplicate name { } else { tuple.add(id.image, unit_type); } } token = get(); if (token.code == TokenCode.Is) { forget(); EXPRESSION expr = EXPRESSION.parse(null, context); foreach (Token id in ids) { if (tuple.exists(id.image)) { } else { tuple.add(id.image, expr); } } } ids.Clear(); break; case TokenCode.Is: ids.Add(token); // No explicit type for the field(s) but only initializer forget(); EXPRESSION expr2 = EXPRESSION.parse(null, context); foreach (Token id in ids) { if (tuple.exists(id.image)) // Error: duplicate name { } else { tuple.add(id.image, expr2); } } ids.Clear(); break; case TokenCode.RParen: case TokenCode.Semicolon: forget(); Token stop = delimiter; // ')': The end of the tuple type; this means that all previous ids were // actually simple type names. // ';': The end of the current part of the tuple type. Again, this means // that all ids were type names. // In both cases, field names were omitted, and we have to assign // artifical names for those fields. ids.Add(token); foreach (Token id in ids) { unit_type = UNIT_REF.parse(id, false, context); count++; string n = "$" + count.ToString(); tuple.add(n, unit_type); } ids.Clear(); if (stop.code == TokenCode.Semicolon) { continue; } else { goto OutLoop; } case TokenCode.LBracket: ids.Add(token); // 'ids' collected before, are actually unit names: // all of them before the last one, were simple names, // and the last one is like 'name[...'. foreach (Token id in ids) { unit_type = UNIT_REF.parse(id, false, context); count++; string n = "$" + count.ToString(); tuple.add(n, unit_type); } break; } // switch } // while OutLoop: tuple.setSpan(begin, token); Debug.WriteLine("Exiting TUPLE_TYPE.parse"); Debug.Unindent(); return(tuple); }
public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = RELATIONAL.parse(first, context); if (result == null) { return(null); } Span begin = result.span; while (true) { Token token = get(); switch (token.code) { case TokenCode.Ampersand: case TokenCode.AmpAmp: case TokenCode.Vertical: case TokenCode.VertVert: forget(); break; case TokenCode.Identifier: Category cat = new Category(CategoryCode.operatorr); if (token.image == "or") { forget(); Token second = get(); if (second.code == TokenCode.Else) { forget(); token = new Token(new Span(token, second), TokenCode.Vertical, "or else", cat); } else { token = new Token(token.span, TokenCode.VertVert, "or", cat); } break; } else if (token.image == "and") { forget(); Token second = get(); if (second.code == TokenCode.Then) { forget(); token = new Token(new Span(token, second), TokenCode.Ampersand, "and then", cat); } else { token = new Token(token.span, TokenCode.AmpAmp, "and", cat); } break; } else { goto Out; } default: goto Out; } EXPRESSION right = RELATIONAL.parse(null, context); result = new LOGICAL(token, result, right); result.setSpan(begin, right.span); } Out: return(result); }
public static void parse(iSCOPE context) // REWRITE!! { Token token = get(); Token begin = token; if (token.code != TokenCode.Catch) // Compiler error { } forget(); CATCH handler = new CATCH(); Context.enter(handler); token = get(); if (token.code != TokenCode.LParen) // Syntax error { } else { forget(); } token = get(); if (token.code != TokenCode.Identifier) // Syntax error { } else { Token id = token; forget(); token = get(); if (token.code == TokenCode.Colon) { forget(); // handler.identifier = id.image; token = get(); if (token.code != TokenCode.Identifier) // Syntax error { } forget(); token = id; } UNIT_REF unit_ref = UNIT_REF.parse(null, false, context); // CHECK!! handler.unit_ref = unit_ref; unit_ref.parent = handler; } token = get(); if (token.code != TokenCode.RParen) // Syntax error { } forget(); BODY.parse(TokenCode.Catch, TokenCode.Else, TokenCode.End, handler); token = get(); // just to get the span... handler.setSpan(begin, token); Context.exit(); context.add(handler); }
/// <summary> /// /// </summary> /// <param name="first"></param> /// <returns></returns> public static EXPRESSION parse(Token first, iSCOPE context) { return(LOGICAL.parse(first, context)); }
/// <summary> /// /// </summary> /// <returns></returns> public static new EXPRESSION parse(Token first, iSCOPE context) { EXPRESSION result = null; Token token = (first == null) ? get() : first; Token begin = token; switch (token.code) { case TokenCode.This: forget(); UNIT unit = Context.unit(); if (unit == null) { // Error message! result = new THIS(null); } else { result = new THIS(unit); result.setSpan(token); } break; case TokenCode.Return: if (!ENTITY.weAreWithinEnsure) { break; } forget(); ROUTINE routine = Context.routine(); if (routine == null) { } // error else { result = new RETURN_EXPR(routine); result.setSpan(token); } break; case TokenCode.Old: forget(); result = EXPRESSION.parse(null, context); Span end = result.span; OLD old = new OLD(result); result.parent = old; result = old; result.setSpan(begin.span, end); break; case TokenCode.If: result = CONDITIONAL.parse(context); break; case TokenCode.LParen: forget(); Span start_tuple = token.span; result = EXPRESSION.parse(null, context); token = get(); if (token.code == TokenCode.Comma) { // Seems to be a tuple forget(); TUPLE_EXPR tuple = new TUPLE_EXPR(); tuple.add(result); while (true) { EXPRESSION expr = EXPRESSION.parse(null, context); tuple.add(expr); token = get(); if (token.code != TokenCode.Comma) { break; } forget(); } result = tuple; } end = expect(TokenCode.RParen).span; result.setSpan(token.span, end); break; case TokenCode.Identifier: if (first == null) { forget(); ////// perhaps the same condition should be added for all cases? } DECLARATION d = Context.find(token); if (d == null) { result = new UNRESOLVED(context, new IDENTIFIER(token)); } else { result = new REFERENCE(d); } Token token2 = get(); if (token2.code == TokenCode.LBracket) { UNIT_REF unitRef = UNIT_REF.parse(token, false, context); result = new NEW(unitRef); result.setSpan(unitRef.span); } else { result.setSpan(token); } break; case TokenCode.Integer: case TokenCode.Real: case TokenCode.String: case TokenCode.Character: result = new LITERAL(token.value, token.span, token.code); result.setSpan(token); forget(); break; default: return(null); } // result.setSpan(token); return(result); }
public static void parse(Token routineName, bool hidden, bool final, bool isOverride, int pure_safe, iSCOPE context) { ROUTINE routine = null; if (routineName.code == TokenCode.Init) { Debug.Indent(); Debug.WriteLine("Entering INITIALIZER.parse"); routine = new INITIALIZER(); goto Init; } Debug.Indent(); Debug.WriteLine("Entering ROUTINE.parse (" + routineName.image + ")"); string image = routineName.image; Token token = get(); // What's after the routine name? switch (routineName.image) { case "and": if (token.code == TokenCode.Then) { forget(); image += " then"; Span span = new Span(routineName.span, token.span); routineName = new Token(span, TokenCode.Identifier, image, new Category(CategoryCode.identifier)); } break; case "or": token = get(); if (token.code == TokenCode.Else) { forget(); image += " else"; Span span = new Span(routineName.span, token.span); routineName = new Token(span, TokenCode.Identifier, image, new Category(CategoryCode.identifier)); } break; } routine = new ROUTINE(pure_safe, isOverride, routineName); Init: routine.setSpecs(hidden, final); Context.enter(routine); if (routineName.code == TokenCode.Init) { goto Init2; } token = get(); if (token.code == TokenCode.Alias) { forget(); token = expect(TokenCode.Identifier); routine.alias = new IDENTIFIER(token.image); } if (token.code == TokenCode.LBracket) { // Generic routine forget(); while (true) { var generic = FORMAL_GENERIC.parse(context); routine.add(generic); token = get(); switch (token.code) { case TokenCode.Comma: case TokenCode.Semicolon: forget(); continue; case TokenCode.RBracket: forget(); goto Finish; default: { /* Syntax error */ break; } } } Finish: ; } Init2: token = get(); if (token.code == TokenCode.LParen) { forget(); token = get(); if (token.code == TokenCode.RParen) { // Empty parameter list forget(); goto Weiter; } while (true) { VARIABLE.parse(false, false, false, false, null, null, routine); token = get(); if (token.code == TokenCode.Comma) { forget(); continue; } if (token.code == TokenCode.Semicolon) { forget(); continue; } break; } expect(TokenCode.RParen); } Weiter: token = get(); if (token.code == TokenCode.Colon) { forget(); bool ref_val, conc; // TEMP SOLUTION Span span2; routine.type = VARIABLE.parseTypeSpecifier(routine, out ref_val, out conc, out span2); if (routine.type != null) { routine.type.parent = routine; routine.type.setSpan(span2); } } token = get(); if (token.code == TokenCode.Require) { forget(); token = get(); if (token.code == TokenCode.Else) { forget(); routine.requireElse = true; } while (true) { EXPRESSION precondition = EXPRESSION.parse(null, routine); routine.addPre(precondition); precondition.parent = routine; token = get(); if (token.code == TokenCode.Is || token.code == TokenCode.Arrow) { break; } } } if (token.code == TokenCode.Arrow) { forget(); BODY body = new BODY(); routine.routineBody = body; body.parent = routine; Context.enter(body); EXPRESSION expression = EXPRESSION.parse(null, body); RETURN ret = new RETURN(expression); expression.parent = ret; ret.setSpan(expression.span); ret.parent = body; body.add(ret); body.setSpan(ret.span); Context.exit(); } else if (token.code == TokenCode.Is) { forget(); token = get(); if (token.code == TokenCode.Abstract) { forget(); routine.isAbstract = true; } else if (token.code == TokenCode.Foreign) { forget(); routine.isForeign = true; } else { BODY body = new BODY(); body.parent = routine; routine.routineBody = body; Context.enter(body); BODY.parse(TokenCode.End, TokenCode.Ensure, TokenCode.ERROR, body); Context.exit(); } token = get(); if (token.code == TokenCode.Ensure) { forget(); token = get(); if (token.code == TokenCode.Then) { forget(); routine.ensureThen = true; } ENTITY.weAreWithinEnsure = true; while (true) { EXPRESSION postcondition = EXPRESSION.parse(null, routine); routine.addPre(postcondition); postcondition.parent = routine; token = get(); if (token.code == TokenCode.End) { forget(); break; } } ENTITY.weAreWithinEnsure = false; } else if (!routine.isAbstract && !routine.isForeign) { expect(TokenCode.End); } } token = get(); if (token.code == TokenCode.Semicolon) { forget(); } Context.exit(); context.add(routine); routine.parent = context.self; routine.setSpan(routineName, token); if (routineName.code == TokenCode.Init) { Debug.WriteLine("Exiting INITIALIZER.parse"); } else { Debug.WriteLine("Exiting ROUTINE.parse"); } Debug.Unindent(); }
/// <summary> /// /// </summary> /// <syntax> /// Loop : while BooleanExpression /// loop /// [ invariant PredicateList ] /// [ StatementList ] /// [ variant PredicateList ] /// end [ loop ] /// /// | loop /// [ invariant PredicateList ] /// [ StatementList ] /// [ variant PredicateList ] /// [ while BooleanExpression ] /// end [ loop ] /// </syntax> /// <returns></returns> public static void parse(Token id, iSCOPE context) { Debug.Indent(); Debug.WriteLine("Entering LOOP.parse"); // If id != null, then 'id' is a loop label. // ':' after label is already parsed. LOOP loop = new LOOP(); Context.enter(loop); Token token = get(); Token begin = token; if (token.code == TokenCode.While) { forget(); loop.prefix = true; EXPRESSION whileExpr = EXPRESSION.parse(null, context); token = get(); if (token.code == TokenCode.Loop) { forget(); loop.addw(whileExpr); whileExpr.parent = loop; } else // Syntax error { error(token, "no-loop"); } token = get(); if (token.code == TokenCode.Invariant) { forget(); parseInvariant(loop); } BODY body = new BODY(); body.parent = loop; loop.body = body; Context.enter(body); token = get(); BODY.parse(TokenCode.End, TokenCode.Variant, TokenCode.ERROR, body); body.setSpan(token, get()); Context.exit(); token = get(); if (token.code == TokenCode.Variant) { forget(); parseVariant(loop); } } else if (token.code == TokenCode.Loop) { loop.prefix = false; forget(); token = get(); if (token.code == TokenCode.Invariant) { forget(); parseInvariant(loop); } BODY body = new BODY(); body.parent = loop; loop.body = body; Context.enter(body); token = get(); BODY.parse(TokenCode.End, TokenCode.Variant, TokenCode.While, body); body.setSpan(token, get()); Context.exit(); token = get(); if (token.code == TokenCode.Variant) { forget(); parseVariant(loop); } token = get(); if (token.code == TokenCode.While) { forget(); EXPRESSION whileExpr = EXPRESSION.parse(null, context); loop.addw(whileExpr); whileExpr.parent = loop; } } else // Compiler error { error(token, "system-bug"); } token = get(); if (token.code != TokenCode.End) // Syntax error { error(token, "no-end", "loop"); } else { forget(); token = get(); if (token.code == TokenCode.Loop) { forget(); } } if (loop != null) { loop.setSpan(begin, token); } context.add(loop); Context.exit(); Debug.WriteLine("Exiting LOOP.parse"); Debug.Unindent(); }
public UNRESOLVED(iSCOPE context, IDENTIFIER n) { ownScope = context; name = n; }