Skip to content

Commit

Permalink
feat: Added initial classes with fields and methods. Added dot operat…
Browse files Browse the repository at this point in the history
…or for fields and methods too
  • Loading branch information
alinalihassan committed May 21, 2022
1 parent c6ce9fa commit 57f0dff
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 84 deletions.
4 changes: 2 additions & 2 deletions src/liblesma/AST/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ namespace lesma {
std::vector<FuncDecl *> methods;

public:
Class(llvm::SMRange Loc, std::string identifier, std::vector<VarDecl *> fields) : Statement(Loc), identifier(std::move(identifier)), fields(std::move(fields)){};
Class(llvm::SMRange Loc, std::string identifier, std::vector<VarDecl *> fields, std::vector<FuncDecl *> methods) : Statement(Loc), identifier(std::move(identifier)), fields(std::move(fields)), methods(std::move(methods)){};
~Class() override = default;

[[nodiscard]] [[maybe_unused]] std::string getIdentifier() const { return identifier; }
Expand All @@ -563,7 +563,7 @@ namespace lesma {
std::string methods_str;
for (auto method: methods)
methods_str += method->toString(srcMgr, 0);
return fmt::format("{}Class[Line({}-{}):Col({}-{})]: {} with: {}\n{}\n",
return fmt::format("{}Class[Line({}-{}):Col({}-{})]: {} with: \n{}\n{}\n",
std::string(ind, ' '),
srcMgr->getLineAndColumn(getStart()).first,
srcMgr->getLineAndColumn(getEnd()).first,
Expand Down
243 changes: 174 additions & 69 deletions src/liblesma/Backend/Codegen.cpp

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/liblesma/Backend/Codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace lesma {

std::vector<std::string> ObjectFiles;
llvm::Function *TopLevelFunc;
SymbolTableEntry *classSymbol = nullptr;
bool isBreak = false;
bool isReturn = false;
bool isJIT = false;
Expand Down Expand Up @@ -96,11 +97,13 @@ namespace lesma {
llvm::Value *visit(Else *node) override;

// TODO: Helper functions, move them out somewhere
SymbolType getType(llvm::Type *type);
SymbolType *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);
llvm::Type *GetExtendedType(llvm::Type *left, llvm::Type *right);
std::string getMangledName(llvm::SMRange span, std::string func_name, const std::vector<llvm::Type *> &paramTypes);
std::string getTypeMangledName(llvm::SMRange span, llvm::Type *type);
llvm::Value *genFuncCall(FuncCall *node, std::vector<llvm::Value *> extra_params);
int FindIndexInFields(SymbolType *_struct, const std::string& field);
};
}// namespace lesma
19 changes: 13 additions & 6 deletions src/liblesma/Frontend/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ Statement *Parser::ParseVarDecl() {
expr = ParseExpression();

if (type == std::nullopt && expr == std::nullopt)
throw LexerError(llvm::SMRange{startTok->getStart(), var->getEnd()}, "Expected either a type or a value");
throw ParserError(llvm::SMRange{startTok->getStart(), var->getEnd()}, "Expected either a type or a value");
else if (expr == std::nullopt && !mutable_)
throw LexerError(llvm::SMRange{startTok->getStart(), type.value()->getEnd()}, "Cannot declare an immutable variable without an initial expression");
throw ParserError(llvm::SMRange{startTok->getStart(), type.value()->getEnd()}, "Cannot declare an immutable variable without an initial expression");

ConsumeNewline();
return new VarDecl({startTok->getStart(), expr != std::nullopt ? expr.value()->getEnd() : type.value()->getEnd()}, var, type, expr, mutable_);
Expand Down Expand Up @@ -437,6 +437,11 @@ Statement *Parser::ParseFunctionDeclaration() {
if (AdvanceIfMatchAny<TokenType::EXTERN_FUNC>())
extern_func = true;

if (extern_func && inClass) {
Error(Previous(), "Extern functions are not allowed in class definition.");
return nullptr;
}

auto identifier = Consume(TokenType::IDENTIFIER);

// Parse parameters
Expand Down Expand Up @@ -511,18 +516,20 @@ Statement *Parser::ParseClass() {
std::vector<FuncDecl *> methods;
Consume(TokenType::INDENT);

inClass = true;
while (!CheckAny<TokenType::DEDENT, TokenType::EOF_TOKEN>()) {
if (CheckAny<TokenType::LET, TokenType::VAR>())
fields.push_back(dynamic_cast<VarDecl *>(ParseVarDecl()));
if (CheckAny<TokenType::DEF>())
else if (CheckAny<TokenType::DEF>())
methods.push_back(dynamic_cast<FuncDecl *>(ParseFunctionDeclaration()));

Consume(TokenType::NEWLINE);
else
Consume(TokenType::NEWLINE);
}
inClass = false;

AdvanceIfMatchAny<TokenType::DEDENT>();

return new Class(loc, token->lexeme, fields);
return new Class(loc, token->lexeme, fields, methods);
}

Statement *Parser::ParseEnum() {
Expand Down
1 change: 1 addition & 0 deletions src/liblesma/Frontend/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace lesma {

const std::vector<Token *> tokens;
unsigned long index;
bool inClass = false;
Compound *tree;

static void Error(Token *token, const std::string &basicString);
Expand Down
10 changes: 5 additions & 5 deletions src/liblesma/Symbol/SymbolTableEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ namespace lesma {
*/
class SymbolTableEntry {
public:
SymbolTableEntry(std::string name, const SymbolType &type) : name(std::move(name)), state(INITIALIZED),
SymbolTableEntry(std::string name, SymbolType *type) : name(std::move(name)), state(INITIALIZED),
type(type), mutable_(false),
signed_(true) {}
SymbolTableEntry(std::string name, const SymbolType &type, SymbolState state) : name(std::move(name)), state(state),
SymbolTableEntry(std::string name, SymbolType *type, SymbolState state) : name(std::move(name)), state(state),
type(type), mutable_(false),
signed_(true) {}
SymbolTableEntry(std::string name, const SymbolType &type,
SymbolTableEntry(std::string name, SymbolType *type,
SymbolState state, bool mutable_, bool signed_) : name(std::move(name)), state(state),
type(type), mutable_(mutable_),
signed_(signed_) {}
Expand All @@ -35,7 +35,7 @@ namespace lesma {
[[nodiscard]] bool getMutability() const { return mutable_; }
[[nodiscard]] bool getSigned() const { return signed_; }
[[nodiscard]] SymbolState getState() { return state; }
[[nodiscard]] SymbolType getType() { return type; }
[[nodiscard]] SymbolType *getType() { return type; }
[[nodiscard]] bool isUsed() { return used; }

void setLLVMValue(llvm::Value *value) { llvmValue = value; }
Expand All @@ -55,7 +55,7 @@ namespace lesma {
private:
std::string name;
SymbolState state;
SymbolType type;
SymbolType *type;
llvm::Value *llvmValue = nullptr;
llvm::Type *llvmType = nullptr;
bool mutable_;
Expand Down
2 changes: 1 addition & 1 deletion src/liblesma/Symbol/SymbolType.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum SymbolSuperType {
TY_STRING,
TY_BOOL,
TY_FUNCTION,
TY_STRUCT,
TY_CLASS,
TY_ENUM,
TY_VOID,
};
Expand Down

0 comments on commit 57f0dff

Please sign in to comment.