ClassAst Class(string[] metadata, Visibility visibility) { Match(TokenKind.ClassKeyword); Token name = Match(TokenKind.Identifier); Match(TokenKind.LeftBrace); List <FieldAst> fields = new List <FieldAst>(); while (current.kind is not TokenKind.Eof and not TokenKind.Semicol) { int start = pos; fields.Add(Field(fields)); // maybe made function? if (current.kind is TokenKind.LeftParen) { BadCode.Report(new SyntaxError("func is not field", tokens[start])); break; } if (current.kind is not TokenKind.Semicol) { Match(TokenKind.Comma); } } EndLine(); List <FuncAst> funcs = new List <FuncAst>(); while (current.kind is not TokenKind.Eof and not TokenKind.RightBrace) { funcs.Add(Func(name.text, fields.ToArray())); } Match(TokenKind.RightBrace); MaybeEndLine(); var clazz = new ClassAst(metadata, visibility, name, fields.ToArray(), funcs.ToArray()); ctnrs.Add(clazz); return(clazz); }
LiteralExprAst LiteralExpr() { switch (current.kind) { case TokenKind.Str: return(new StrLiteralExprAst(current, Next().text)); case TokenKind.CStr: return(new CStrLiteralExprAst(current, Next().text)); case TokenKind.Char: return(new CharLiteralExprAst(current, Next().text[0], 8)); case TokenKind.NullKeyword: return(new NullLiteralExprAst(Next())); case TokenKind.Hex: return(new IntLiteralExprAst(current, ulong.Parse(Next().text, NumberStyles.HexNumber))); case TokenKind.FHex: return(new FloatLiteralExprAst(current, double.Parse(Next().text, NumberStyles.HexNumber))); case TokenKind.Int: return(new IntLiteralExprAst(current, ulong.Parse(Next().text, NumberStyles.Integer))); case TokenKind.Float: return(new FloatLiteralExprAst(current, double.Parse(Next().text, NumberStyles.Float))); case TokenKind.TrueKeyword: Next(); return(new BoolLiteralExprAst(current, true)); case TokenKind.FalseKeyword: Next(); return(new BoolLiteralExprAst(current, false)); default: BadCode.Report(new SyntaxError("not a literal", current)); return(new LiteralExprAst(current)); } }
public Parser(string source, string file) { scope = new Scope(this); folder = Path.GetFileName(Path.GetDirectoryName(file) !); filename = Path.GetFileName(file); parsers.Add(folder + filename, this); Preprocessor preprocessor = new Preprocessor(source, folder, filename); tokens = preprocessor.PreProcess(); foreach (Token token in tokens) { if (token.kind is TokenKind.Unknown) { BadCode.Report(new SyntaxError("unrecognized token", token)); } else if (token.kind is TokenKind.HashTag) { throw new Exception("preprocessor directive after preprocessing!!"); } } }
BreakStmtAst Break() { Token keywrd = Match(TokenKind.BreakKeyword); int depth = 1; if (current.kind is not TokenKind.Semicol) { Token depthKwrd = Next(); if (depthKwrd.kind is not TokenKind.Int) { BadCode.Report(new SyntaxError("expected positive integer above 0", depthKwrd)); MaybeEndLine(); return(new BreakStmtAst(keywrd, depth)); } depth = int.Parse(depthKwrd.text); if (depth <= 0) { BadCode.Report(new SyntaxError("expected positive integer above 0", depthKwrd)); } } EndLine(); return(new BreakStmtAst(keywrd, depth)); }
ExprAst PrimExpr() { switch (current.kind) { case TokenKind.Percent: Token op = Next(); return(new PreExprAst(PreOpcode(op.kind), op, PrimExpr())); case TokenKind.Identifier: { if (scope.VarExists(current.text)) { return(new VarExprAst(Next())); } if (current.text is "stalloc") { return(StallocExpr()); } if (current.text is "sizeof") { return(SizeofExpr()); } if (scope.FuncExists(current.text)) // fnptr overloads { return(new FuncPtrAst(Next())); } if (!IsType(current)) { BadCode.Report(new SyntaxError($"symbol '{current.text}' doesn't exist", current)); } TypeAst type = Type(); if (current.kind is TokenKind.LeftBracket) { return(ArrayExpr(eleType: type)); } return(GroupExpr(groupType: type)); } case TokenKind.LeftParen: Next(); if (IsType(current)) { TypeAst to = Type(); Token open = Match(TokenKind.RightParen); ExprAst value = PreExpr(); return(new CastExprAst(value, open, to)); } ExprAst expr = Expr(); Match(TokenKind.RightParen); return(expr); case TokenKind.LeftBracket: if (IsType(next)) { Next(); TypeAst to = Type(); Token open = Match(TokenKind.RightBracket); ExprAst value = PreExpr(); return(new BitCastExprAst(value, open, to)); } return(ArrayExpr()); default: return(LiteralExpr()); } }