diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/cps/AST.h | 27 | ||||
| -rw-r--r-- | include/cps/ArrayHandler.h | 11 | ||||
| -rw-r--r-- | include/cps/CodeGen.h | 7 | ||||
| -rw-r--r-- | include/cps/FileAST.h | 16 | ||||
| -rw-r--r-- | include/cps/FunctionAST.h | 8 | ||||
| -rw-r--r-- | include/cps/FunctionGen.h | 14 | ||||
| -rw-r--r-- | include/cps/Identifier.h | 27 | ||||
| -rw-r--r-- | include/cps/Lexer.h | 5 | ||||
| -rw-r--r-- | include/cps/Parser.h | 6 | ||||
| -rw-r--r-- | include/cps/TypeAST.h | 6 | ||||
| -rw-r--r-- | include/cps/TypeSystem.h | 5 |
11 files changed, 81 insertions, 51 deletions
diff --git a/include/cps/AST.h b/include/cps/AST.h index 1afc359..5aadc21 100644 --- a/include/cps/AST.h +++ b/include/cps/AST.h @@ -6,8 +6,18 @@ namespace cps { -class ExprAST { +class SourceLocation { + int SourceLine = 0; public: + explicit SourceLocation(int Line = 0) : SourceLine(Line) {} + virtual ~SourceLocation() = default; + int getLine() const { return SourceLine; } + void setLine(int Line) { SourceLine = Line; } +}; + +class ExprAST : public SourceLocation { +public: + using SourceLocation::SourceLocation; virtual ~ExprAST() = default; }; @@ -56,13 +66,11 @@ public: class ArrayAccessExprAST : public ExprAST { std::string Name; std::vector<std::unique_ptr<ExprAST>> Indices; - int Line; public: ArrayAccessExprAST(const std::string &Name, std::vector<std::unique_ptr<ExprAST>> Indices, int Line) - : Name(Name), Indices(std::move(Indices)), Line(Line) {} + : ExprAST(Line), Name(Name), Indices(std::move(Indices)) {} const std::string &getName() const { return Name; } const std::vector<std::unique_ptr<ExprAST>> &getIndices() const { return Indices; } - int getLine() const { return Line; } }; class UnaryExprAST : public ExprAST { @@ -78,18 +86,17 @@ public: class BinaryExprAST : public ExprAST { int Op; std::unique_ptr<ExprAST> LHS, RHS; - int Line; public: BinaryExprAST(int Op, std::unique_ptr<ExprAST> LHS, std::unique_ptr<ExprAST> RHS, int Line) - : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)), Line(Line) {} + : ExprAST(Line), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} int getOp() const { return Op; } ExprAST *getLHS() const { return LHS.get(); } ExprAST *getRHS() const { return RHS.get(); } - int getLine() const { return Line; } }; -class StmtAST { +class StmtAST : public SourceLocation { public: + using SourceLocation::SourceLocation; virtual ~StmtAST() = default; }; @@ -154,14 +161,12 @@ class ArrayAssignStmtAST : public StmtAST { std::string Name; std::vector<std::unique_ptr<ExprAST>> Indices; std::unique_ptr<ExprAST> Expr; - int Line; public: ArrayAssignStmtAST(const std::string &Name, std::vector<std::unique_ptr<ExprAST>> Indices, std::unique_ptr<ExprAST> Expr, int Line) - : Name(Name), Indices(std::move(Indices)), Expr(std::move(Expr)), Line(Line) {} + : StmtAST(Line), Name(Name), Indices(std::move(Indices)), Expr(std::move(Expr)) {} const std::string &getName() const { return Name; } const std::vector<std::unique_ptr<ExprAST>> &getIndices() const { return Indices; } ExprAST *getExpr() const { return Expr.get(); } - int getLine() const { return Line; } }; class InputStmtAST : public StmtAST { diff --git a/include/cps/ArrayHandler.h b/include/cps/ArrayHandler.h index def174a..843bdc8 100644 --- a/include/cps/ArrayHandler.h +++ b/include/cps/ArrayHandler.h @@ -1,4 +1,5 @@ #pragma once +#include "cps/Identifier.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -28,10 +29,10 @@ class ArrayHandler { llvm::LLVMContext *TheContext; llvm::IRBuilder<> *Builder; llvm::Module *TheModule; - std::map<std::string, SymbolInfo> *Symbols; + IdentifierMap<SymbolInfo> *Symbols; TypeSystem &Types; - std::map<std::string, ArrayMetadata> ArrayTable; + IdentifierMap<ArrayMetadata> ArrayTable; RuntimeCheck &RuntimeChecker; llvm::FunctionCallee MallocFunc; @@ -63,7 +64,7 @@ public: ArrayHandler(llvm::LLVMContext &C, llvm::IRBuilder<> &B, llvm::Module &M, - std::map<std::string, SymbolInfo> &Sym, + IdentifierMap<SymbolInfo> &Sym, TypeSystem &TS, RuntimeCheck &RC); @@ -89,12 +90,12 @@ public: // Swap in a fresh table (function bodies get their own scope, mirroring // the Symbols save/clear/restore discipline); returns the previous table. - std::map<std::string, ArrayMetadata> exchangeTable(std::map<std::string, ArrayMetadata> NewTable); + IdentifierMap<ArrayMetadata> exchangeTable(IdentifierMap<ArrayMetadata> NewTable); // Copy for block-scoping: control-flow bodies snapshot before and restore // after, so an array declared inside a branch cannot be referenced past it // (its buffer setup and bound SSA values live inside the branch). - std::map<std::string, ArrayMetadata> snapshotTable() const { return ArrayTable; } + IdentifierMap<ArrayMetadata> snapshotTable() const { return ArrayTable; } // Callee side of an array parameter: rebuild metadata from the incoming // data pointer + per-dim bounds. MakeCopy (BYVAL) mallocs and memcpys the diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h index 2ba5e79..3c80eb8 100644 --- a/include/cps/CodeGen.h +++ b/include/cps/CodeGen.h @@ -1,4 +1,6 @@ #pragma once +#include "llvm/Support/SaveAndRestore.h" +#include "cps/Identifier.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -27,10 +29,11 @@ class CodeGen { std::unique_ptr<llvm::LLVMContext> TheContext; std::unique_ptr<llvm::Module> TheModule; std::unique_ptr<llvm::IRBuilder<>> Builder; - std::map<std::string, SymbolInfo> Symbols; + int DiagnosticLine = 0; + IdentifierMap<SymbolInfo> Symbols; struct ConstantScope { unsigned ID; - std::map<std::string, std::optional<SymbolInfo>> Saved; + IdentifierMap<std::optional<SymbolInfo>> Saved; }; std::vector<ConstantScope> ConstantScopes = {{0, {}}}; unsigned NextScopeID = 1; diff --git a/include/cps/FileAST.h b/include/cps/FileAST.h index 04bd06a..a151597 100644 --- a/include/cps/FileAST.h +++ b/include/cps/FileAST.h @@ -9,55 +9,47 @@ namespace cps { class OpenFileStmtAST : public StmtAST { std::unique_ptr<ExprAST> FileName; FileMode Mode; - int Line; public: OpenFileStmtAST(std::unique_ptr<ExprAST> FileName, FileMode Mode, int Line) - : FileName(std::move(FileName)), Mode(Mode), Line(Line) {} + : StmtAST(Line), FileName(std::move(FileName)), Mode(Mode) {} ExprAST *getFileName() const { return FileName.get(); } FileMode getMode() const { return Mode; } - int getLine() const { return Line; } }; class ReadFileStmtAST : public StmtAST { std::unique_ptr<ExprAST> FileName; std::string VarName; - int Line; public: ReadFileStmtAST(std::unique_ptr<ExprAST> FileName, const std::string &VarName, int Line) - : FileName(std::move(FileName)), VarName(VarName), Line(Line) {} + : StmtAST(Line), FileName(std::move(FileName)), VarName(VarName) {} ExprAST *getFileName() const { return FileName.get(); } const std::string &getVarName() const { return VarName; } - int getLine() const { return Line; } }; class WriteFileStmtAST : public StmtAST { std::unique_ptr<ExprAST> FileName; std::unique_ptr<ExprAST> Data; - int Line; public: WriteFileStmtAST(std::unique_ptr<ExprAST> FileName, std::unique_ptr<ExprAST> Data, int Line) - : FileName(std::move(FileName)), Data(std::move(Data)), Line(Line) {} + : StmtAST(Line), FileName(std::move(FileName)), Data(std::move(Data)) {} ExprAST *getFileName() const { return FileName.get(); } ExprAST *getData() const { return Data.get(); } - int getLine() const { return Line; } }; class CloseFileStmtAST : public StmtAST { std::unique_ptr<ExprAST> FileName; - int Line; public: CloseFileStmtAST(std::unique_ptr<ExprAST> FileName, int Line) - : FileName(std::move(FileName)), Line(Line) {} + : StmtAST(Line), FileName(std::move(FileName)) {} ExprAST *getFileName() const { return FileName.get(); } - int getLine() const { return Line; } }; } // namespace cps diff --git a/include/cps/FunctionAST.h b/include/cps/FunctionAST.h index 66ac728..0c2d0b5 100644 --- a/include/cps/FunctionAST.h +++ b/include/cps/FunctionAST.h @@ -58,29 +58,25 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector<std::unique_ptr<ExprAST>> Args; - int Line; public: CallExprAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line) - : Callee(Callee), Args(std::move(Args)), Line(Line) {} + : ExprAST(Line), Callee(Callee), Args(std::move(Args)) {} const std::string &getCallee() const { return Callee; } const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; } - int getLine() const { return Line; } }; class CallStmtAST : public StmtAST { std::string Callee; std::vector<std::unique_ptr<ExprAST>> Args; - int Line; public: CallStmtAST(const std::string &Callee, std::vector<std::unique_ptr<ExprAST>> Args, int Line) - : Callee(Callee), Args(std::move(Args)), Line(Line) {} + : StmtAST(Line), Callee(Callee), Args(std::move(Args)) {} const std::string &getCallee() const { return Callee; } const std::vector<std::unique_ptr<ExprAST>> &getArgs() const { return Args; } - int getLine() const { return Line; } }; diff --git a/include/cps/FunctionGen.h b/include/cps/FunctionGen.h index 80c91ea..4bf4519 100644 --- a/include/cps/FunctionGen.h +++ b/include/cps/FunctionGen.h @@ -1,4 +1,5 @@ #pragma once +#include "cps/Identifier.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "cps/FunctionAST.h" @@ -34,6 +35,7 @@ struct ParamSig { // dispatch on declared parameter types and modes instead of inferring them // back from LLVM types. struct FuncSig { + std::string Name; std::string ReturnTypeName; std::vector<ParamSig> Params; }; @@ -55,10 +57,12 @@ private: TypeSystem &Types; ExceptionHandler &Exceptions; - std::map<std::string, SymbolInfo> &Symbols; + IdentifierMap<SymbolInfo> &Symbols; bool &HadError; + int &DiagnosticLine; + void reportError(const char *Fmt, ...); - std::map<std::string, FuncSig> Signatures; + IdentifierMap<FuncSig> Signatures; ArrayParamBinder BindArrayParam; void createArgumentAllocas(llvm::Function *F, const std::vector<ParamDecl> &Params); @@ -69,9 +73,9 @@ public: llvm::IRBuilder<> &B, TypeSystem &TS, ExceptionHandler &EH, - std::map<std::string, SymbolInfo> &Sym, - bool &HadErrorFlag) - : Context(C), Module(M), Builder(B), Types(TS), Exceptions(EH), Symbols(Sym), HadError(HadErrorFlag) {} + IdentifierMap<SymbolInfo> &Sym, + bool &HadErrorFlag, int &Line) + : Context(C), Module(M), Builder(B), Types(TS), Exceptions(EH), Symbols(Sym), HadError(HadErrorFlag), DiagnosticLine(Line) {} llvm::Type *getLLVMType(const std::string &TypeName); diff --git a/include/cps/Identifier.h b/include/cps/Identifier.h new file mode 100644 index 0000000..c35f636 --- /dev/null +++ b/include/cps/Identifier.h @@ -0,0 +1,27 @@ +#pragma once +#include <algorithm> +#include <map> +#include <set> +#include <string> + +namespace cps { + +inline unsigned char foldIdentifier(unsigned char C) { + return C >= 'A' && C <= 'Z' ? C + ('a' - 'A') : C; +} + +struct IdentifierLess { + bool operator()(const std::string &A, const std::string &B) const { + return std::lexicographical_compare(A.begin(), A.end(), B.begin(), B.end(), + [](unsigned char L, unsigned char R) { return foldIdentifier(L) < foldIdentifier(R); }); + } +}; + +inline bool sameIdentifier(const std::string &A, const std::string &B) { + return !IdentifierLess{}(A, B) && !IdentifierLess{}(B, A); +} + +template<class T> using IdentifierMap = std::map<std::string, T, IdentifierLess>; +using IdentifierSet = std::set<std::string, IdentifierLess>; + +} // namespace cps diff --git a/include/cps/Lexer.h b/include/cps/Lexer.h index efedec8..749ae0b 100644 --- a/include/cps/Lexer.h +++ b/include/cps/Lexer.h @@ -25,7 +25,6 @@ enum Token { tok_endif = -9, tok_while = -10, - tok_do = -11, tok_endwhile = -12, tok_repeat = -13, @@ -116,7 +115,7 @@ class Lexer { struct TokenData { int Kind, Line; std::string Identifier, String; - int64_t Integer; + uint64_t Integer; double Real; char Character; }; @@ -129,7 +128,7 @@ public: std::string IdentifierStr; std::string StringVal; - int64_t NumVal = 0; + uint64_t NumVal = 0; double RealVal = 0; char CharVal = '\0'; diff --git a/include/cps/Parser.h b/include/cps/Parser.h index 0079c8b..fdbb99a 100644 --- a/include/cps/Parser.h +++ b/include/cps/Parser.h @@ -1,4 +1,5 @@ #pragma once +#include "cps/Identifier.h" #include "cps/Lexer.h" #include "cps/AST.h" #include "cps/TypeAST.h" @@ -24,7 +25,7 @@ class Parser { unsigned BlockDepth = 0; // ParseBlock nesting; 1 = top level std::map<int, int> BinopPrecedence; - std::set<std::string> TypeNames = { + IdentifierSet TypeNames = { "INTEGER", "REAL", "BOOLEAN", "STRING", "CHAR", "VOID", "C_INT", "C_CHAR", "C_STRING", "C_DOUBLE" }; @@ -33,7 +34,9 @@ class Parser { int GetTokPrecedence(); std::unique_ptr<ExprAST> ParseExpression(); + std::unique_ptr<ExprAST> ParseUnaryImpl(); std::unique_ptr<ExprAST> ParseUnary(); + std::unique_ptr<ExprAST> ParsePrimaryImpl(); std::unique_ptr<ExprAST> ParsePrimary(); std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS); @@ -71,6 +74,7 @@ class Parser { std::unique_ptr<StmtAST> ParseCallStmt(); std::unique_ptr<StmtAST> ParseReturnStmt(); std::optional<std::vector<ParamDecl>> ParsePrototypeArgs(bool AllowByRef); + bool ParseIntegerValue(bool Negative, int64_t &Out); bool ParseSignedIntBound(int64_t &Out); std::unique_ptr<StmtAST> ParseOpenFile(); diff --git a/include/cps/TypeAST.h b/include/cps/TypeAST.h index 873ca4a..edf2ee5 100644 --- a/include/cps/TypeAST.h +++ b/include/cps/TypeAST.h @@ -81,7 +81,7 @@ public: const std::vector<RecordFieldDecl> &getFields() const { return Fields; } }; -// CLASS <name> with explicitly PUBLIC/PRIVATE fields, ending in ENDCLASS. +// CLASS <name> with default-public or explicit PUBLIC/PRIVATE fields, ending in ENDCLASS. // Storage and value semantics are inherited from record declarations. class ClassTypeDeclAST : public RecordTypeDeclAST { public: @@ -107,17 +107,15 @@ struct DesignatorAccess { class DesignatorExprAST : public ExprAST { std::string BaseName; std::vector<DesignatorAccess> Accesses; - int Line; public: DesignatorExprAST(const std::string &BaseName, std::vector<DesignatorAccess> Accesses, int Line) - : BaseName(BaseName), Accesses(std::move(Accesses)), Line(Line) {} + : ExprAST(Line), BaseName(BaseName), Accesses(std::move(Accesses)) {} const std::string &getBaseName() const { return BaseName; } const std::vector<DesignatorAccess> &getAccesses() const { return Accesses; } - int getLine() const { return Line; } }; // ^<designator> — address-of. The operand is a designator by construction, diff --git a/include/cps/TypeSystem.h b/include/cps/TypeSystem.h index b615ed8..8bee6b9 100644 --- a/include/cps/TypeSystem.h +++ b/include/cps/TypeSystem.h @@ -1,4 +1,5 @@ #pragma once +#include "cps/Identifier.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" @@ -112,8 +113,8 @@ struct SymbolInfo { class TypeSystem { llvm::LLVMContext &Context; - std::map<std::string, TypeInfo> Types; - std::map<std::string, EnumConstant> EnumConstants; + IdentifierMap<TypeInfo> Types; + IdentifierMap<EnumConstant> EnumConstants; void registerBuiltins(); const TypeInfo *registerType(const std::string &TypeName, |
