Skip to content

Commit

Permalink
feat: massive refactoring, using our Value and Type classes instead o…
Browse files Browse the repository at this point in the history
…f llvm's
  • Loading branch information
alinalihassan committed Apr 20, 2023
1 parent 6dbe072 commit 9fecfa6
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 418 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ set(COMMON_SOURCES
src/liblesma/Token/Token.cpp
src/liblesma/Backend/Codegen.cpp
src/liblesma/Symbol/SymbolTable.cpp
src/liblesma/Symbol/Type.cpp
src/liblesma/Driver/Driver.cpp
)

Expand Down
709 changes: 379 additions & 330 deletions src/liblesma/Backend/Codegen.cpp

Large diffs are not rendered by default.

26 changes: 15 additions & 11 deletions src/liblesma/Backend/Codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ namespace lesma {
SymbolTable *Scope;
std::string filename;
std::string alias;
llvm::Value *result = nullptr;
llvm::Type *result_type = nullptr;
lesma::Value *result = nullptr;

std::stack<llvm::BasicBlock *> breakBlocks;
std::stack<llvm::BasicBlock *> continueBlocks;
std::stack<std::vector<Statement *>> deferStack;

std::vector<std::string> ObjectFiles;
std::vector<std::string> ImportedModules;
std::vector<std::tuple<Function *, const FuncDecl *, Value *>> Prototypes;
std::vector<std::tuple<lesma::Value *, const FuncDecl *, Value *>> Prototypes;
llvm::Function *TopLevelFunc;
Value *selfSymbol = nullptr;
bool isBreak = false;
Expand Down Expand Up @@ -112,17 +111,22 @@ namespace lesma {
void visit(const TypeExpr *node) override;

// TODO: Helper functions, move them out somewhere
static Type *getType(llvm::Type *type);
llvm::Value *Cast(llvm::SMRange span, llvm::Value *val, llvm::Type *type);
llvm::Value *Cast(llvm::SMRange span, llvm::Value *val, llvm::Type *type, bool isStore);
static llvm::Type *GetExtendedType(llvm::Type *left, llvm::Type *right);
// Type related helper functions
lesma::Value *Cast(llvm::SMRange span, lesma::Value *val, lesma::Type *type);
lesma::Value *Cast(llvm::SMRange span, lesma::Value *val, lesma::Type *type, bool isStore);
static lesma::Type *GetExtendedType(lesma::Type *left, lesma::Type *right);

// Name mangling functions and such
static bool isMethod(const std::string &mangled_name);
std::string getMangledName(llvm::SMRange span, std::string func_name, const std::vector<llvm::Type *> &paramTypes, bool isMethod = false, std::string alias = "");
std::string getMangledName(llvm::SMRange span, std::string func_name, const std::vector<lesma::Type *> &paramTypes, bool isMethod = false, std::string alias = "");
[[maybe_unused]] static bool isMangled(std::string name);
static std::string getDemangledName(const std::string &mangled_name);
std::string getTypeMangledName(llvm::SMRange span, llvm::Type *type);
llvm::Value *genFuncCall(const FuncCall *node, const std::vector<llvm::Value *> &extra_params);
std::string getTypeMangledName(llvm::SMRange span, lesma::Type *type);

// Other
lesma::Value *genFuncCall(const FuncCall *node, const std::vector<lesma::Value *> &extra_params);
static int FindIndexInFields(Type *_struct, const std::string &field);
void defineFunction(Function *F, const FuncDecl *node, Value *clsSymbol);
static lesma::Type *FindTypeInFields(Type *_struct, const std::string &field);
void defineFunction(lesma::Value *value, const FuncDecl *node, Value *clsSymbol);
};
}// namespace lesma
4 changes: 2 additions & 2 deletions src/liblesma/Symbol/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ Value *SymbolTable::lookup(const std::string &name) {
*/
Value *SymbolTable::lookupStructByName(const std::string &name) {
for (auto sym: symbols) {
if (sym.second->getLLVMType() != nullptr && sym.second->getLLVMType()->isStructTy() &&
llvm::cast<llvm::StructType>(sym.second->getLLVMType())->getName() == name)
if (sym.second->getType()->getLLVMType() != nullptr && sym.second->getType()->isOneOf({TY_CLASS, TY_ENUM}) &&
llvm::cast<llvm::StructType>(sym.second->getType()->getLLVMType())->getName() == name)
return sym.second;
}

Expand Down
56 changes: 0 additions & 56 deletions src/liblesma/Symbol/Type.cpp

This file was deleted.

48 changes: 35 additions & 13 deletions src/liblesma/Symbol/Type.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <algorithm>
#include <llvm/IR/Type.h>
#include <map>
#include <memory>
#include <string>
Expand All @@ -15,6 +16,8 @@ namespace lesma {
TY_FLOAT,
TY_STRING,
TY_BOOL,
TY_PTR,
TY_ARRAY,
TY_VOID,
TY_FUNCTION,
TY_CLASS,
Expand All @@ -31,22 +34,41 @@ namespace lesma {

class Type {
BaseType baseType;
llvm::Type *llvmType;

Type *elementType;
Type *returnType;
std::vector<std::unique_ptr<Field>> fields;
bool signedInt = true;

public:
// Constructors
explicit Type(BaseType superType) : baseType(superType), elementType(nullptr), fields() {}
explicit Type(BaseType superType, std::vector<std::unique_ptr<Field>> fields, Type *elementType) : baseType(superType), elementType(elementType), fields(std::move(fields)) {}

// Public methods
[[nodiscard]] bool is(BaseType superType) const;
[[nodiscard]] bool isPrimitive() const;
[[nodiscard]] bool isOneOf(const std::vector<BaseType> &superTypes) const;
[[nodiscard]] BaseType getBaseType() const;
[[nodiscard]] Type *getElementType() const;
[[nodiscard]] std::vector<std::unique_ptr<Field>> const &getFields() const;
friend bool operator==(const Type &lhs, const Type &rhs);
friend bool operator!=(const Type &lhs, const Type &rhs);
explicit Type(BaseType baseType) : baseType(baseType), llvmType(nullptr), elementType(nullptr), fields() {}
explicit Type(BaseType baseType, llvm::Type *llvmType) : baseType(baseType), llvmType(llvmType), elementType(nullptr), fields() {}
explicit Type(BaseType baseType, llvm::Type *llvmType, Type *elementType) : baseType(baseType), llvmType(llvmType), elementType(elementType), fields() {}
explicit Type(BaseType baseType, llvm::Type *llvmType, std::vector<std::unique_ptr<Field>> fields) : baseType(baseType), llvmType(llvmType), elementType(nullptr), fields(std::move(fields)) {}

[[nodiscard]] bool is(BaseType type) const { return baseType == type; }
[[nodiscard]] bool isPrimitive() const { return isOneOf({TY_INT, TY_FLOAT, TY_STRING, TY_BOOL}); }
[[nodiscard]] bool isOneOf(const std::vector<BaseType> &baseTypes) const {
return std::any_of(baseTypes.begin(), baseTypes.end(), [this](int type) { return type == this->baseType; });
}
[[nodiscard]] BaseType getBaseType() const { return baseType; }
[[nodiscard]] Type *getElementType() const { return elementType; }
[[nodiscard]] Type *getReturnType() const { return returnType; }
[[nodiscard]] llvm::Type *getLLVMType() const { return llvmType; }
[[nodiscard]] std::vector<std::unique_ptr<Field>> const &getFields() const { return fields; }
[[nodiscard]] bool isSigned() const { return signedInt; }

void setLLVMType(llvm::Type *type) { llvmType = type; }
void setBaseType(BaseType type) { baseType = type; }
void setElementType(lesma::Type *type) { elementType = type; }
void setReturnType(lesma::Type *type) { returnType = type; }

friend bool operator==(const Type &lhs, const Type &rhs) {
return lhs.getBaseType() == rhs.getBaseType();
}
friend bool operator!=(const Type &lhs, const Type &rhs) {
return !(lhs == rhs);
}
};
}// namespace lesma
11 changes: 7 additions & 4 deletions src/liblesma/Symbol/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ namespace lesma {
*/
class Value {
public:
explicit Value(Type *type) : state(INITIALIZED),
type(type), mutableVar(false),
signedVar(true) {}
Value(std::string name, Type *type) : name(std::move(name)), state(INITIALIZED),
type(type), mutableVar(false),
signedVar(true) {}
Value(std::string name, Type *type, llvm::Value *value) : name(std::move(name)), state(INITIALIZED),
type(type), llvmValue(value), mutableVar(false),
signedVar(true) {}
Value(std::string name, Type *type, SymbolState state) : name(std::move(name)), state(state),
type(type), mutableVar(false),
signedVar(true) {}
Expand All @@ -31,7 +37,6 @@ namespace lesma {

[[nodiscard]] std::string getName() { return name; }
[[nodiscard]] llvm::Value *getLLVMValue() { return llvmValue; }
[[nodiscard]] llvm::Type *getLLVMType() { return llvmType; }
[[nodiscard]] bool getMutability() const { return mutableVar; }
[[nodiscard]] bool getSigned() const { return signedVar; }
[[nodiscard]] SymbolState getState() { return state; }
Expand All @@ -40,7 +45,6 @@ namespace lesma {
[[nodiscard]] bool isUsed() const { return used; }

void setLLVMValue(llvm::Value *value) { llvmValue = value; }
void setLLVMType(llvm::Type *type_) { llvmType = type_; }
void setUsed(bool used_) { used = used_; }
void setSigned(bool signed_) { mutableVar = signed_; }
void setMutable(bool mutable_) { mutableVar = mutable_; }
Expand All @@ -49,7 +53,7 @@ namespace lesma {
std::string toString() {
std::string type_str, value_str;
llvm::raw_string_ostream rso(type_str), rso2(value_str);
llvmType->print(rso);
type->getLLVMType()->print(rso);
llvmValue->print(rso2);
return name + ": " + type_str + " = " + value_str;
}
Expand All @@ -59,7 +63,6 @@ namespace lesma {
SymbolState state;
Type *type;
llvm::Value *llvmValue = nullptr;
llvm::Type *llvmType = nullptr;
bool mutableVar;
bool signedVar;
bool used = false;
Expand Down
2 changes: 1 addition & 1 deletion src/stdlib/base.les
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export def strToFloat(x: str) -> float
return strtod(x)

export def random(x: int, y: int) -> int
srand(time(null as *int))
srand(time(0))
if x < y
return x + rand() % (y - x)

Expand Down

0 comments on commit 9fecfa6

Please sign in to comment.