diff options
| author | _ov4 <hausemasterstream@gmail.com> | 2026-03-27 01:50:32 +0000 |
|---|---|---|
| committer | _ov4 <hausemasterstream@gmail.com> | 2026-03-27 01:50:32 +0000 |
| commit | f2b051ae3e28135cc02589f3f698c43743cca48e (patch) | |
| tree | 91582f514eda6665c8283875dd0b3ee491cc62ea /include | |
| parent | 15f30a397a222e9256d41e8b8a7b6fff454b02da (diff) | |
feat: generalize typed array support
Diffstat (limited to 'include')
| -rw-r--r-- | include/cps/AST.h | 7 | ||||
| -rw-r--r-- | include/cps/ArrayHandler.h | 41 | ||||
| -rw-r--r-- | include/cps/CodeGen.h | 18 | ||||
| -rw-r--r-- | include/cps/FunctionGen.h | 13 | ||||
| -rw-r--r-- | include/cps/Lexer.h | 3 | ||||
| -rw-r--r-- | include/cps/Parser.h | 2 | ||||
| -rw-r--r-- | include/cps/TypeSystem.h | 71 |
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 |
