internal VarDecl ParseForDecl(bool implied) { Token n = null; if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La())) { n = ConsumeAndGet(); } Require(n, ErrorCode.Expected, "identifier"); Expr init = null; if (Require(TokenType.ASSIGN_OP)) { init = ParseExpression(); } TypeExpr type = null; if (!implied && Expect(TokenType.AS)) { type = Require(ParseType(), ErrorCode.Expected, "type"); } return(implied ? new ImpliedVarDecl(n, init) : new VarDecl(n, null, type, init)); }
internal IdExpr ParseId() { if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La())) { return(new IdExpr(ConsumeAndGet())); } return(null); }
Token RequireId() { if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La())) { return(ConsumeAndGet()); } throw Error(Lt(), ErrorCode.Expected, "identifier"); }
internal Token ParseIdName() { Token n = null; if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La())) { n = ConsumeAndGet(); } return(n); }
internal NameExpr ParseQualifiedName() { NameExpr n = ParseName(); while (La() == TokenType.DOT && (La(2) == TokenType.ID || TokenAttr.IsSoftKeyword(La(2)))) { Consume(); n = new QualifiedNameExpr(n, ParseName()); } return(n); }
internal TypeExpr ParseType() { var t = La(); switch (t) { case TokenType.ID: return(ParseTypeSuffix(ParseQualifiedName())); case TokenType.ARRAY: case TokenType.BINARY: case TokenType.CODEBLOCK: case TokenType.CURRENCY: case TokenType.DATE: case TokenType.FLOAT: case TokenType.PSZ: case TokenType.SYMBOL: case TokenType.USUAL: return(ParseTypeSuffix(new NativeTypeExpr(ConsumeAndGet()))); case TokenType.BYTE: case TokenType.CHAR: case TokenType.DATETIME: case TokenType.DECIMAL: case TokenType.DWORD: case TokenType.DYNAMIC: case TokenType.INT: case TokenType.INT64: case TokenType.LOGIC: case TokenType.LONGINT: case TokenType.OBJECT: case TokenType.PTR: case TokenType.REAL4: case TokenType.REAL8: case TokenType.SHORTINT: case TokenType.STRING: case TokenType.UINT64: case TokenType.VOID: case TokenType.WORD: return(ParseTypeSuffix(new NativeTypeExpr(ConsumeAndGet()))); default: if (TokenAttr.IsSoftKeyword(La())) { return(ParseTypeSuffix(ParseQualifiedName())); } return(null); } }
internal Token ParseVarIdName() { if (La() == TokenType.ID) { return(ConsumeAndGet()); } else if (La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3)))) { Consume(2); return(ConsumeAndGet()); } else if (TokenAttr.IsSoftKeyword(La())) { return(ConsumeAndGet()); } return(null); }
internal Expr ParseFieldAlias() { if (La(2) == TokenType.ALIAS) { if (La(3) == TokenType.LPAREN || La(3) == TokenType.AMP || La(4) == TokenType.LPAREN) { return(null); } if (Expect(TokenType.FIELD)) { Require(Expect(TokenType.ALIAS), ErrorCode.Expected, "->"); } var alias = Require(ParseId(), ErrorCode.Expected, "name"); if (La() == TokenType.ALIAS) { Token o = ConsumeAndGet(); var field = Require(ParseId(), ErrorCode.Expected, "name"); return((_options.AllowMemvarAlias && alias.Token.type == TokenType.M) ? new MemvarExpr(new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o) as Expr : new AliasExpr(new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o)); } else { return(new AliasExpr(null, new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), alias.Token)); } } if (_options.AllowMemvarAlias && La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3)))) { Consume(); var o = ConsumeAndGet(); var v = Require(ParseId(), ErrorCode.Expected, "name"); return(new MemvarExpr(new LiteralExpr(v.Token, TokenType.SYMBOL_CONST), o)); } return(null); }
internal Expr ParseTerm() { #if DEBUG if (!CanParseTerm()) { return(null); } #endif var t = La(); switch (t) { case TokenType.ID: return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName()))); case TokenType.SELF: return(new SelfExpr(ConsumeAndGet())); case TokenType.SUPER: return(new SuperExpr(ConsumeAndGet())); case TokenType.CHECKED: { var o = ConsumeAndGet(); return(new CheckedExpr(ParseParenExpr(), o)); } case TokenType.UNCHECKED: { var o = ConsumeAndGet(); return(new UncheckedExpr(ParseParenExpr(), o)); } case TokenType.TYPEOF: { var o = ConsumeAndGet(); return(new TypeOfExpr(ParseParenType(), o)); } case TokenType.SIZEOF: { var o = ConsumeAndGet(); return(new SizeOfExpr(ParseParenType(), o)); } case TokenType.DEFAULT: { var o = ConsumeAndGet(); return(new DefaultExpr(ParseParenType(), o)); } case TokenType.TRUE_CONST: case TokenType.FALSE_CONST: case TokenType.CHAR_CONST: case TokenType.STRING_CONST: case TokenType.ESCAPED_STRING_CONST: case TokenType.INTERPOLATED_STRING_CONST: case TokenType.SYMBOL_CONST: case TokenType.HEX_CONST: case TokenType.BIN_CONST: case TokenType.REAL_CONST: case TokenType.INT_CONST: case TokenType.DATE_CONST: case TokenType.DATETIME_CONST: case TokenType.NIL: case TokenType.NULL: case TokenType.NULL_ARRAY: case TokenType.NULL_CODEBLOCK: case TokenType.NULL_DATE: case TokenType.NULL_OBJECT: case TokenType.NULL_PSZ: case TokenType.NULL_PTR: case TokenType.NULL_STRING: case TokenType.NULL_SYMBOL: return(new LiteralExpr(ConsumeAndGet())); case TokenType.INCOMPLETE_STRING_CONST: throw Error(Lt(), ErrorCode.UnterminatedString); case TokenType.INVALID_NUMBER: throw Error(Lt(), ErrorCode.InvalidNumber); case TokenType.ARRAY: case TokenType.DATE: case TokenType.DATETIME: if (TokenAttr.IsSoftKeyword(La()) && La(2) == TokenType.LPAREN) { return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName()))); } return(ParseNativeTypeOrCast(new NativeTypeExpr(ConsumeAndGet()))); case TokenType.CODEBLOCK: case TokenType.FLOAT: case TokenType.PSZ: case TokenType.SYMBOL: case TokenType.USUAL: case TokenType.BYTE: case TokenType.CHAR: case TokenType.DECIMAL: case TokenType.DWORD: case TokenType.DYNAMIC: case TokenType.INT: case TokenType.INT64: case TokenType.LOGIC: case TokenType.LONGINT: case TokenType.OBJECT: case TokenType.PTR: case TokenType.REAL4: case TokenType.REAL8: case TokenType.SHORTINT: case TokenType.STRING: case TokenType.UINT64: case TokenType.VOID: case TokenType.WORD: return(ParseNativeTypeOrCast(new NativeTypeExpr(ConsumeAndGet()))); case TokenType.LPAREN: return(ParseParenExpr()); case TokenType.LCURLY: return(ParseLiteralArrayOrCodeblock()); case TokenType.LT: return(ParseTypedLiteralArray()); case TokenType.IF: case TokenType.IIF: return(ParseIif()); case TokenType.FIELD: return(ParseFieldAlias()); // TODO nvk: PTR LPAREN Type=datatype COMMA Expr=expression RPAREN #voCastPtrExpression // PTR( typeName, expr ) // TODO nvk: Op=(VO_AND | VO_OR | VO_XOR | VO_NOT) LPAREN Exprs+=expression (COMMA Exprs+=expression)* RPAREN #intrinsicExpression // _Or(expr, expr, expr) // TODO nvk: AMP LPAREN Expr=expression RPAREN #macro // &( expr ) // TODO nvk: AMP Id=identifierName #macro // &id case TokenType.ARGLIST: if (_options.ParseStatements) { throw Error(Lt(), ErrorCode.NotSupported, Lt()?.value); } else { goto default; } case TokenType.VO_AND: case TokenType.VO_OR: case TokenType.VO_XOR: case TokenType.VO_NOT: return(ParseIntrinsicFunction()); default: if (TokenAttr.IsSoftKeyword(La())) { return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName()))); } return(null); } }
internal bool CanParseTerm() { switch (La()) { case TokenType.ID: case TokenType.SELF: case TokenType.SUPER: case TokenType.CHECKED: case TokenType.UNCHECKED: case TokenType.TYPEOF: case TokenType.SIZEOF: case TokenType.DEFAULT: case TokenType.TRUE_CONST: case TokenType.FALSE_CONST: case TokenType.CHAR_CONST: case TokenType.STRING_CONST: case TokenType.ESCAPED_STRING_CONST: case TokenType.INTERPOLATED_STRING_CONST: case TokenType.SYMBOL_CONST: case TokenType.HEX_CONST: case TokenType.BIN_CONST: case TokenType.REAL_CONST: case TokenType.INT_CONST: case TokenType.DATE_CONST: case TokenType.DATETIME_CONST: case TokenType.NIL: case TokenType.NULL: case TokenType.NULL_ARRAY: case TokenType.NULL_CODEBLOCK: case TokenType.NULL_DATE: case TokenType.NULL_OBJECT: case TokenType.NULL_PSZ: case TokenType.NULL_PTR: case TokenType.NULL_STRING: case TokenType.NULL_SYMBOL: case TokenType.INCOMPLETE_STRING_CONST: case TokenType.INVALID_NUMBER: case TokenType.ARRAY: case TokenType.CODEBLOCK: case TokenType.DATE: case TokenType.FLOAT: case TokenType.PSZ: case TokenType.SYMBOL: case TokenType.USUAL: case TokenType.BYTE: case TokenType.CHAR: case TokenType.DATETIME: case TokenType.DECIMAL: case TokenType.DWORD: case TokenType.DYNAMIC: case TokenType.INT: case TokenType.INT64: case TokenType.LOGIC: case TokenType.LONGINT: case TokenType.OBJECT: case TokenType.PTR: case TokenType.REAL4: case TokenType.REAL8: case TokenType.SHORTINT: case TokenType.STRING: case TokenType.UINT64: case TokenType.VOID: case TokenType.WORD: case TokenType.LPAREN: case TokenType.LCURLY: case TokenType.IIF: case TokenType.FIELD: case TokenType.VO_AND: case TokenType.VO_OR: case TokenType.VO_XOR: case TokenType.VO_NOT: return(true); case TokenType.ARGLIST: return(_options.ParseStatements); case TokenType.LT: { var p = Mark(); var la = ParseTypedLiteralArray(); Rewind(p); return(la != null); } default: return(TokenAttr.IsSoftKeyword(La())); } }
internal Expr ParseFieldAlias() { if (La(2) == TokenType.ALIAS) { if (La(3) == TokenType.LPAREN || La(3) == TokenType.AMP || La(4) == TokenType.LPAREN) { return(null); } if (Expect(TokenType.FIELD)) { Require(Expect(TokenType.ALIAS), ErrorCode.Expected, "->"); } var alias = Require(ParseId(), ErrorCode.Expected, "name"); if (La() == TokenType.ALIAS) { Token o = ConsumeAndGet(); var field = Require(ParseId(), ErrorCode.Expected, "name"); // M-> and MEMVAR-> should not become an AliasExpr if (alias.Token.Type == TokenType.MEMVAR || alias.Token.Type == TokenType.M || alias.Token.SourceText.ToUpper() == "MEMVAR" || alias.Token.SourceText.ToUpper() == "_MEMVAR" || alias.Token.SourceText.ToUpper() == "M") { return(new MemvarExpr(new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o)); } return(new AliasExpr(new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o)); } else { return(new AliasExpr(null, new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), alias.Token)); } } if (_options.AllowMemvarAlias && La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3)))) { Consume(); var o = ConsumeAndGet(); var v = Require(ParseId(), ErrorCode.Expected, "name"); return(new MemvarExpr(new LiteralExpr(v.Token, TokenType.SYMBOL_CONST), o)); } return(null); }
internal SwitchStmt ParseSwitchStmt() { ExpectAny(TokenType.BEGIN, TokenType.DO); var t = RequireAndGet(TokenType.SWITCH); var e = RequireExpression(); Require(TokenType.EOS); var sbs = new List <SwitchBlock>(); sbs.Add(Require(ParseSwitchBlock(), ErrorCode.Expected, "CASE")); while (ParseSwitchBlock() is SwitchBlock sb) { sbs.Add(sb); } Require(TokenType.END); Expect(TokenType.SWITCH); Require(TokenType.EOS); return(new SwitchStmt(t, e, sbs.ToArray())); SwitchBlock ParseSwitchBlock() { if (La() == TokenType.CASE && ( (La(2) == TokenType.M && La(3) == TokenType.DOT && (La(4) == TokenType.ID || TokenAttr.IsSoftKeyword(La(4))) && La(5) == TokenType.AS) || ((La(2) == TokenType.ID || TokenAttr.IsSoftKeyword(La(2))) && La(3) == TokenType.AS) )) { var st = ConsumeAndGet(); var n = RequireVarIdName(); Require(TokenType.AS); var ty = Require(ParseType(), ErrorCode.Expected, "type"); Expr wh = null; if (Expect(TokenType.WHEN)) { wh = ParseExpression(); } Require(TokenType.EOS); var s = ParseStatementBlock(); return(new SwitchBlockType(st, n, ty, wh, s.StmtList.Length > 0 ? s : null)); } else if (La() == TokenType.CASE) { var st = ConsumeAndGet(); var se = RequireExpression(); Require(se is LiteralExpr, ErrorCode.Expected, "literal value"); Expr wh = null; if (Expect(TokenType.WHEN)) { wh = ParseExpression(); } Require(TokenType.EOS); var s = ParseStatementBlock(); return(new SwitchBlockExpr(st, se, wh, s.StmtList.Length > 0 ? s : null)); } else if (La() == TokenType.OTHERWISE) { var st = ConsumeAndGet(); Require(TokenType.EOS); var s = ParseStatementBlock(); return(new SwitchBlock(st, s.StmtList.Length > 0 ? s : null)); } else { return(null); } } }