aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
author_ov4 <hausemasterstream@gmail.com>2026-03-27 01:50:32 +0000
committer_ov4 <hausemasterstream@gmail.com>2026-03-27 01:50:32 +0000
commitf2b051ae3e28135cc02589f3f698c43743cca48e (patch)
tree91582f514eda6665c8283875dd0b3ee491cc62ea /include
parent15f30a397a222e9256d41e8b8a7b6fff454b02da (diff)
feat: generalize typed array support
Diffstat (limited to 'include')
-rw-r--r--include/cps/AST.h7
-rw-r--r--include/cps/ArrayHandler.h41
-rw-r--r--include/cps/CodeGen.h18
-rw-r--r--include/cps/FunctionGen.h13
-rw-r--r--include/cps/Lexer.h3
-rw-r--r--include/cps/Parser.h2
-rw-r--r--include/cps/TypeSystem.h71
7 files changed, 139 insertions, 16 deletions
diff --git a/include/cps/AST.h b/include/cps/AST.h
index f07e937..f24d987 100644
--- a/include/cps/AST.h
+++ b/include/cps/AST.h
@@ -32,6 +32,13 @@ public:
bool getVal() const { return Val; }
};
+class CharExprAST : public ExprAST {
+ char Val;
+public:
+ CharExprAST(char Val) : Val(Val) {}
+ char getVal() const { return Val; }
+};
+
class StringExprAST : public ExprAST {
std::string Val;
public:
diff --git a/include/cps/ArrayHandler.h b/include/cps/ArrayHandler.h
index 1ee91db..f15004f 100644
--- a/include/cps/ArrayHandler.h
+++ b/include/cps/ArrayHandler.h
@@ -4,6 +4,8 @@
#include "llvm/IR/Module.h"
#include "cps/AST.h"
#include "cps/RuntimeCheck.h"
+#include "cps/TypeSystem.h"
+#include <cstdint>
#include <map>
#include <string>
#include <vector>
@@ -11,11 +13,13 @@
namespace cps {
struct ArrayMetadata {
- int Rank;
- llvm::Type* ElementType;
+ int Rank = 0;
+ std::string ElementTypeName;
+ llvm::Type *ElementType = nullptr;
+ uint64_t ElementSize = 0;
std::vector<llvm::Value*> LowerBounds;
std::vector<llvm::Value*> UpperBounds;
- std::vector<llvm::Value*> Multipliers;
+ std::vector<llvm::Value*> Multipliers;
};
class CodeGen;
@@ -25,6 +29,8 @@ class ArrayHandler {
llvm::IRBuilder<> *Builder;
llvm::Module *TheModule;
std::map<std::string, llvm::Value*> *NamedValues;
+ std::map<std::string, SymbolInfo> *Symbols;
+ TypeSystem &Types;
std::map<std::string, ArrayMetadata> ArrayTable;
RuntimeCheck &RuntimeChecker;
@@ -32,22 +38,31 @@ class ArrayHandler {
llvm::FunctionCallee MallocFunc;
llvm::FunctionCallee FreeFunc;
- llvm::Value* computeFlatIndex(const std::string &Name, const std::vector<llvm::Value*> &Indices);
-
- void emitPrintLoop(const std::string &Name, int CurrentDim, std::vector<llvm::Value*> CurrentIndices, llvm::FunctionCallee PrintfFunc, llvm::Value* FmtStr);
+ llvm::Value *computeFlatIndex(const std::string &Name, const std::vector<llvm::Value*> &Indices);
+ llvm::Value *getArrayBasePointer(const std::string &Name);
+ llvm::Value *getElementPointer(const std::string &Name, llvm::Value *Offset);
+ const ArrayMetadata *getMetadata(const std::string &Name) const;
+ void emitPrintLoop(const std::string &Name,
+ int CurrentDim,
+ std::vector<llvm::Value*> CurrentIndices,
+ CodeGen &CG);
public:
- ArrayHandler(llvm::LLVMContext &C, llvm::IRBuilder<> &B, llvm::Module &M, std::map<std::string, llvm::Value*> &NV);
+ ArrayHandler(llvm::LLVMContext &C,
+ llvm::IRBuilder<> &B,
+ llvm::Module &M,
+ std::map<std::string, llvm::Value*> &NV,
+ std::map<std::string, SymbolInfo> &Sym,
+ TypeSystem &TS,
+ RuntimeCheck &RC);
void setupExternalFunctions();
-
+
void emitArrayDeclare(ArrayDeclareStmtAST *Stmt, CodeGen &CG);
void emitArrayAssign(ArrayAssignStmtAST *Stmt, CodeGen &CG);
- ArrayHandler(llvm::LLVMContext &C, llvm::IRBuilder<> &B, llvm::Module &M, std::map<std::string, llvm::Value*> &NV, RuntimeCheck &RC);
-
- llvm::Value* emitArrayAccess(ArrayAccessExprAST *Expr, CodeGen &CG);
+ llvm::Value *emitArrayAccess(ArrayAccessExprAST *Expr, CodeGen &CG);
- bool tryEmitArrayOutput(ExprAST *Expr, CodeGen &CG, llvm::FunctionCallee PrintfFunc, llvm::Value* FmtStr);
+ bool tryEmitArrayOutput(ExprAST *Expr, CodeGen &CG);
};
-}
+} // namespace cps
diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h
index 121f30d..07ff3e8 100644
--- a/include/cps/CodeGen.h
+++ b/include/cps/CodeGen.h
@@ -5,6 +5,7 @@
#include "cps/AST.h"
#include "cps/RuntimeCheck.h"
#include "cps/FunctionGen.h"
+#include "cps/TypeSystem.h"
#include "cps/IntegerHandler.h"
#include "cps/RealHandler.h"
@@ -16,6 +17,7 @@
#include <map>
#include <memory>
+#include <string>
namespace cps {
@@ -26,6 +28,8 @@ class CodeGen {
std::unique_ptr<llvm::Module> TheModule;
std::unique_ptr<llvm::IRBuilder<>> Builder;
std::map<std::string, llvm::Value*> NamedValues;
+ std::map<std::string, SymbolInfo> Symbols;
+ std::unique_ptr<TypeSystem> Types;
std::unique_ptr<ArrayHandler> Arrays;
std::unique_ptr<RuntimeCheck> RuntimeChecker;
@@ -45,6 +49,7 @@ class CodeGen {
llvm::Value *PrintfFormatStr; // %lld\n
llvm::Value *PrintfFloatFormatStr; // %f\n
llvm::Value *PrintfStringFormatStr; // %s\n
+ llvm::Value *PrintfCharFormatStr; // %c\n
llvm::Value *ScanfFormatStr; // %lld
llvm::Value *ScanfFloatFormatStr; // %lf
@@ -52,9 +57,18 @@ class CodeGen {
llvm::Value *TrueStr; // "TRUE"
llvm::Value *FalseStr; // "FALSE"
+ llvm::Value *EmptyStringStr; // ""
void SetupExternalFunctions();
llvm::AllocaInst *CreateEntryBlockAlloca(llvm::Function *TheFunction, const std::string &VarName);
+ llvm::AllocaInst *CreateEntryBlockAlloca(llvm::Function *TheFunction, llvm::Type *AllocType, const std::string &VarName);
+
+ void registerSymbol(const std::string &Name, llvm::Value *Storage, const std::string &TypeName, bool IsArray = false);
+ const SymbolInfo *getSymbolInfo(const std::string &Name) const;
+ const TypeInfo *getExprTypeInfo(ExprAST *Expr) const;
+ llvm::Value *coerceValueToType(llvm::Value *Val, const TypeInfo *TargetInfo);
+ void emitDeclareStmt(DeclareStmtAST *Stmt);
+ void emitOutputValue(llvm::Value *Val, const TypeInfo *TypeInfo, bool AppendNewline = true);
void emitIfStmt(IfStmtAST *Stmt);
void emitWhileStmt(WhileStmtAST *Stmt);
@@ -69,6 +83,10 @@ public:
llvm::Value *emitExpr(ExprAST *Expr);
void emitStmt(StmtAST *Stmt);
+
+ const TypeInfo *resolveType(const std::string &TypeName) const;
+ llvm::Type *getLLVMType(const std::string &TypeName) const;
+ llvm::Value *getNamedValue(const std::string &Name) const;
friend class ArrayHandler;
};
diff --git a/include/cps/FunctionGen.h b/include/cps/FunctionGen.h
index 84a2858..7ebb7f4 100644
--- a/include/cps/FunctionGen.h
+++ b/include/cps/FunctionGen.h
@@ -2,6 +2,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "cps/FunctionAST.h"
+#include "cps/TypeSystem.h"
#include <map>
#include <vector>
#include <functional>
@@ -14,15 +15,21 @@ class FunctionGen {
llvm::LLVMContext &Context;
llvm::Module &Module;
llvm::IRBuilder<> &Builder;
+ TypeSystem &Types;
std::map<std::string, llvm::Value*> &NamedValues;
+ std::map<std::string, SymbolInfo> &Symbols;
void createArgumentAllocas(llvm::Function *F, const std::vector<std::tuple<std::string, std::string, bool>> &Args);
public:
- FunctionGen(llvm::LLVMContext &C, llvm::Module &M, llvm::IRBuilder<> &B,
- std::map<std::string, llvm::Value*> &NV)
- : Context(C), Module(M), Builder(B), NamedValues(NV) {}
+ FunctionGen(llvm::LLVMContext &C,
+ llvm::Module &M,
+ llvm::IRBuilder<> &B,
+ TypeSystem &TS,
+ std::map<std::string, llvm::Value*> &NV,
+ std::map<std::string, SymbolInfo> &Sym)
+ : Context(C), Module(M), Builder(B), Types(TS), NamedValues(NV), Symbols(Sym) {}
llvm::Type *getLLVMType(const std::string &TypeName);
diff --git a/include/cps/Lexer.h b/include/cps/Lexer.h
index df84d0b..e8d2609 100644
--- a/include/cps/Lexer.h
+++ b/include/cps/Lexer.h
@@ -49,6 +49,8 @@ enum Token {
tok_ucase = -35,
tok_string_literal = -36,
tok_left = -37,
+ tok_char_kw = -38,
+ tok_char_literal = -39,
tok_identifier = -100,
tok_number_int = -101,
@@ -83,6 +85,7 @@ public:
std::string StringVal;
int64_t NumVal;
double RealVal;
+ char CharVal = '\0';
int gettok();
int getLine() const { return CurrentLine; }
diff --git a/include/cps/Parser.h b/include/cps/Parser.h
index 877c684..19f49be 100644
--- a/include/cps/Parser.h
+++ b/include/cps/Parser.h
@@ -5,6 +5,7 @@
#include <memory>
#include <map>
#include <tuple>
+#include <string>
namespace cps {
@@ -25,6 +26,7 @@ class Parser {
std::unique_ptr<ExprAST> ParseNumberExpr();
std::unique_ptr<ExprAST> ParseIdentifierExpr();
std::unique_ptr<ExprAST> ParseParenExpr();
+ std::string ParseTypeName(bool AllowVoid = false);
std::unique_ptr<ExprAST> ParseStringBuiltin(const std::string &FuncName);
diff --git a/include/cps/TypeSystem.h b/include/cps/TypeSystem.h
new file mode 100644
index 0000000..32c348f
--- /dev/null
+++ b/include/cps/TypeSystem.h
@@ -0,0 +1,71 @@
+#pragma once
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Type.h"
+#include <cstdint>
+#include <map>
+#include <string>
+
+namespace cps {
+
+enum class TypeKind {
+ Integer,
+ Real,
+ Boolean,
+ String,
+ Char,
+ Void,
+ Custom
+};
+
+struct TypeInfo {
+ std::string Name;
+ llvm::Type *LLVMType = nullptr;
+ uint64_t ElementSize = 0;
+ TypeKind Kind = TypeKind::Custom;
+ bool Printable = false;
+ bool Builtin = false;
+ bool ReferenceLike = false;
+
+ bool isNumeric() const;
+ bool isIntegral() const;
+ bool isReal() const;
+ bool isBoolean() const;
+ bool isString() const;
+ bool isChar() const;
+ bool isVoid() const;
+};
+
+struct SymbolInfo {
+ llvm::Value *Storage = nullptr;
+ std::string TypeName;
+ bool IsArray = false;
+};
+
+class TypeSystem {
+ llvm::LLVMContext &Context;
+ std::map<std::string, TypeInfo> Types;
+
+ void registerBuiltins();
+
+public:
+ explicit TypeSystem(llvm::LLVMContext &Ctx);
+
+ const TypeInfo *resolve(const std::string &TypeName) const;
+ bool hasType(const std::string &TypeName) const;
+
+ const TypeInfo *registerType(const std::string &TypeName,
+ llvm::Type *LLVMType,
+ uint64_t ElementSize,
+ TypeKind Kind = TypeKind::Custom,
+ bool Printable = false,
+ bool ReferenceLike = false,
+ bool Builtin = false);
+
+ llvm::Type *getLLVMType(const std::string &TypeName) const;
+ uint64_t getElementSize(const std::string &TypeName) const;
+ llvm::Constant *getZeroValue(const std::string &TypeName) const;
+};
+
+} // namespace cps