aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cps/AST.h27
-rw-r--r--include/cps/ArrayHandler.h11
-rw-r--r--include/cps/CodeGen.h7
-rw-r--r--include/cps/FileAST.h16
-rw-r--r--include/cps/FunctionAST.h8
-rw-r--r--include/cps/FunctionGen.h14
-rw-r--r--include/cps/Identifier.h27
-rw-r--r--include/cps/Lexer.h5
-rw-r--r--include/cps/Parser.h6
-rw-r--r--include/cps/TypeAST.h6
-rw-r--r--include/cps/TypeSystem.h5
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,