Compare commits

...

3 Commits

Author SHA1 Message Date
85644457d0 Tokenize whitespace as well, skip it in next 2026-04-12 00:49:59 +03:00
cdff4cc9db Add binops for more fundamental type kinds 2026-04-12 00:47:38 +03:00
01434b8097 Eliminate repetition 2026-04-12 00:46:36 +03:00
3 changed files with 35 additions and 54 deletions

View File

@ -99,6 +99,9 @@ namespace token {
Token TokenStream::next() {
token::Token got = this->peek(0);
m_position++;
while (m_position < static_cast<int>(m_tokens.size()) && this->peek().type == Type::Whitespace) {
m_position++;
}
return got;
}
@ -187,8 +190,7 @@ namespace token {
if ((i + 1) >= text_length) break;
c = text[++i];
} while (iswhitespace(c));
// tokens.push_back(token::Token{ token::Type::Whitespace, content });
// Just skip whitespace tokens
tokens.push_back(token::Token{ token::Type::Whitespace, content, meta + content.size() });
}
else {
tokens.push_back(token::Token{ token::Type::Symbol, std::string{c}, meta });

View File

@ -53,7 +53,24 @@ namespace types {
}
}
std::optional<std::shared_ptr<Type>> FundamentalType::return_type() {
llvm::Value* Type::add(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for this type");
}
llvm::Value* Type::sub(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for this type");
}
llvm::Value* Type::lt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for this type");
}
llvm::Value* Type::gt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for this type");
}
std::optional<std::shared_ptr<Type>> Type::return_type() {
return {};
}
@ -65,6 +82,8 @@ namespace types {
llvm::Value* FundamentalType::add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateAdd(lhs, rhs, "add");
default:
throw std::runtime_error("Invalid type for add");
@ -74,6 +93,8 @@ namespace types {
llvm::Value* FundamentalType::sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateSub(lhs, rhs, "sub");
default:
throw std::runtime_error("Invalid type");
@ -83,6 +104,8 @@ namespace types {
llvm::Value* FundamentalType::lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SLT, lhs, rhs, "cmp");
default:
throw std::runtime_error("Invalid type");
@ -92,6 +115,8 @@ namespace types {
llvm::Value* FundamentalType::gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SGT, lhs, rhs);
default:
throw std::runtime_error("Invalid type");
@ -128,52 +153,16 @@ namespace types {
return std::pair(ptr, self);
}
llvm::Value* FunctionType::add(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for functions");
}
llvm::Value* FunctionType::sub(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for functions");
}
llvm::Value* FunctionType::lt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for functions");
}
llvm::Value* FunctionType::gt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for functions");
}
std::string PointerType::formatted() {
std::stringstream out{ "" };
out << this->m_inner->formatted() << "*";
return out.str();
}
std::optional<std::shared_ptr<Type>> PointerType::return_type() {
return {};
}
std::pair<llvm::Value*, std::shared_ptr<Type>> PointerType::load(codegen::Builder& builder, llvm::Value* ptr) {
return std::pair(
builder.builder->CreateLoad(this->m_inner->codegen(builder), ptr),
this->m_inner
);
}
llvm::Value* PointerType::add(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for pointers");
}
llvm::Value* PointerType::sub(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for pointers");
}
llvm::Value* PointerType::lt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for pointers");
}
llvm::Value* PointerType::gt(codegen::Builder&, llvm::Value*, llvm::Value*) {
throw std::runtime_error("Invalid operation for pointers");
}
}

View File

@ -31,11 +31,11 @@ namespace types {
virtual std::string formatted() = 0;
virtual llvm::Type* codegen(codegen::Builder& builder) = 0;
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) = 0;
virtual std::optional<std::shared_ptr<Type>> return_type() = 0;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual std::optional<std::shared_ptr<Type>> return_type();
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
};
class FundamentalType : public Type {
@ -47,7 +47,6 @@ namespace types {
virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) override;
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
virtual std::optional<std::shared_ptr<Type>> return_type() override;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
@ -69,10 +68,6 @@ namespace types {
virtual llvm::Type* codegen(codegen::Builder& builder) override;
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
virtual std::optional<std::shared_ptr<Type>> return_type() override;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
};
@ -88,11 +83,6 @@ namespace types {
virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) override;
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
virtual std::optional<std::shared_ptr<Type>> return_type() override;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
};
}