diff options
Diffstat (limited to 'include/cps')
| -rw-r--r-- | include/cps/AST.h | 16 | ||||
| -rw-r--r-- | include/cps/CodeGen.h | 9 | ||||
| -rw-r--r-- | include/cps/Lexer.h | 25 | ||||
| -rw-r--r-- | include/cps/Parser.h | 10 |
4 files changed, 53 insertions, 7 deletions
diff --git a/include/cps/AST.h b/include/cps/AST.h index e3c6bc5..87c9341 100644 --- a/include/cps/AST.h +++ b/include/cps/AST.h @@ -168,6 +168,22 @@ public: const std::vector<std::unique_ptr<ExprAST>> &getExprs() const { return Exprs; } }; +struct CaseBranch { + std::unique_ptr<ExprAST> Lower, Upper; // Null Lower denotes OTHERWISE. + std::vector<std::unique_ptr<StmtAST>> Body; + int Line; +}; + +class CaseStmtAST : public StmtAST { + std::string Selector; + std::vector<CaseBranch> Branches; +public: + CaseStmtAST(std::string Selector, std::vector<CaseBranch> Branches) + : Selector(std::move(Selector)), Branches(std::move(Branches)) {} + const std::string &getSelector() const { return Selector; } + const std::vector<CaseBranch> &getBranches() const { return Branches; } +}; + class IfStmtAST : public StmtAST { std::unique_ptr<ExprAST> Cond; std::vector<std::unique_ptr<StmtAST>> ThenStmts; diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h index 72b96c6..4259d63 100644 --- a/include/cps/CodeGen.h +++ b/include/cps/CodeGen.h @@ -70,13 +70,17 @@ class CodeGen { llvm::Value *convertNumericValue(llvm::Value *Val, const TypeInfo *Source, const TypeInfo *Target); llvm::Value *emitCast(CastExprAST *Cast); - llvm::Value *emitCBinaryOp(BinaryExprAST *Bin, const TypeInfo *Left, const TypeInfo *Right); + llvm::Value *emitBinaryOp(int Op, llvm::Value *L, const TypeInfo *LT, + llvm::Value *R, const TypeInfo *RT, int Line); + llvm::Value *emitCBinaryOp(int Op, llvm::Value *L, const TypeInfo *Left, + llvm::Value *R, const TypeInfo *Right, int Line); void emitCOutput(llvm::Value *Val, const TypeInfo *Info, bool AppendNewline); void emitCInput(const SymbolInfo *Symbol, const TypeInfo *Info); // TYPE-system registration (Designator.cc) and operators (TypeCheckGen.cc). void runTypePrePass(const std::vector<std::unique_ptr<StmtAST>> &Statements); - llvm::Value *emitUserKindBinaryOp(BinaryExprAST *Bin, const TypeInfo *LT, const TypeInfo *RT); + llvm::Value *emitUserKindBinaryOp(int Op, llvm::Value *L, const TypeInfo *LT, + llvm::Value *R, const TypeInfo *RT, int Line); // An addressable location and the pseudocode type stored there. struct LValueInfo { @@ -95,6 +99,7 @@ class CodeGen { void emitDeclareStmt(DeclareStmtAST *Stmt); void emitOutputValue(llvm::Value *Val, const TypeInfo *TypeInfo, bool AppendNewline = true); + void emitCaseStmt(CaseStmtAST *Stmt); void emitIfStmt(IfStmtAST *Stmt); void emitTryStmt(TryStmtAST *Stmt); void emitWhileStmt(WhileStmtAST *Stmt); diff --git a/include/cps/Lexer.h b/include/cps/Lexer.h index 2f6f231..7f3d5b5 100644 --- a/include/cps/Lexer.h +++ b/include/cps/Lexer.h @@ -2,6 +2,7 @@ #include <istream> #include <string> #include <cstdint> +#include <deque> namespace cps { @@ -13,6 +14,10 @@ enum Token { tok_input = -4, tok_output = -5, + tok_case = -40, + tok_endcase = -41, + tok_otherwise = -42, + tok_if = -6, tok_then = -7, tok_else = -8, @@ -105,18 +110,32 @@ class Lexer { std::istream &Input; int LastChar = ' '; int CurrentLine = 1; + int TokenLine = 1; bool HadError = false; + struct TokenData { + int Kind, Line; + std::string Identifier, String; + int64_t Integer; + double Real; + char Character; + }; + std::deque<TokenData> Lookahead; + int readToken(); + TokenData captureToken(int Kind) const; + void restoreToken(const TokenData &Token); public: explicit Lexer(std::istream &Input) : Input(Input) {} std::string IdentifierStr; std::string StringVal; - int64_t NumVal; - double RealVal; + int64_t NumVal = 0; + double RealVal = 0; char CharVal = '\0'; int gettok(); - int getLine() const { return CurrentLine; } + int peekToken(unsigned Offset = 0); + int peekLine(unsigned Offset = 0); + int getLine() const { return TokenLine; } bool hadError() const { return HadError; } }; diff --git a/include/cps/Parser.h b/include/cps/Parser.h index 5713587..921480d 100644 --- a/include/cps/Parser.h +++ b/include/cps/Parser.h @@ -16,7 +16,10 @@ namespace cps { class Parser { Lexer &Lex; - int CurTok; + int CurTok = tok_eof; + bool StartsLine = true; + bool ParsingCaseLabel = false; + std::vector<unsigned> CaseBodyDepths; unsigned NumErrors = 0; unsigned BlockDepth = 0; // ParseBlock nesting; 1 = top level @@ -41,7 +44,10 @@ class Parser { std::unique_ptr<StmtAST> ParseStatement(); std::unique_ptr<StmtAST> ParseStatementImpl(); - std::vector<std::unique_ptr<StmtAST>> ParseBlock(std::initializer_list<int> Terminators); + std::vector<std::unique_ptr<StmtAST>> ParseBlock(std::initializer_list<int> Terminators, bool CaseBody = false); + bool isCaseLabel(); + bool atCaseBoundary(); + std::unique_ptr<StmtAST> ParseCaseStmt(); std::optional<std::vector<std::unique_ptr<ExprAST>>> ParseExprList(char CloseDelim, bool AllowEmpty); void syncToStatementStart(); std::unique_ptr<StmtAST> ParseIfStmt(); |
