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 TokenStream::next() {
token::Token got = this->peek(0); token::Token got = this->peek(0);
m_position++; m_position++;
while (m_position < static_cast<int>(m_tokens.size()) && this->peek().type == Type::Whitespace) {
m_position++;
}
return got; return got;
} }
@ -187,8 +190,7 @@ namespace token {
if ((i + 1) >= text_length) break; if ((i + 1) >= text_length) break;
c = text[++i]; c = text[++i];
} while (iswhitespace(c)); } while (iswhitespace(c));
// tokens.push_back(token::Token{ token::Type::Whitespace, content }); tokens.push_back(token::Token{ token::Type::Whitespace, content, meta + content.size() });
// Just skip whitespace tokens
} }
else { else {
tokens.push_back(token::Token{ token::Type::Symbol, std::string{c}, meta }); 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 {}; return {};
} }
@ -65,6 +82,8 @@ namespace types {
llvm::Value* FundamentalType::add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) { llvm::Value* FundamentalType::add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateAdd(lhs, rhs, "add"); return builder.builder->CreateAdd(lhs, rhs, "add");
default: default:
throw std::runtime_error("Invalid type for add"); 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) { llvm::Value* FundamentalType::sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateSub(lhs, rhs, "sub"); return builder.builder->CreateSub(lhs, rhs, "sub");
default: default:
throw std::runtime_error("Invalid type"); 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) { llvm::Value* FundamentalType::lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SLT, lhs, rhs, "cmp"); return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SLT, lhs, rhs, "cmp");
default: default:
throw std::runtime_error("Invalid type"); 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) { llvm::Value* FundamentalType::gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SGT, lhs, rhs); return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SGT, lhs, rhs);
default: default:
throw std::runtime_error("Invalid type"); throw std::runtime_error("Invalid type");
@ -128,52 +153,16 @@ namespace types {
return std::pair(ptr, self); 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::string PointerType::formatted() {
std::stringstream out{ "" }; std::stringstream out{ "" };
out << this->m_inner->formatted() << "*"; out << this->m_inner->formatted() << "*";
return out.str(); 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) { std::pair<llvm::Value*, std::shared_ptr<Type>> PointerType::load(codegen::Builder& builder, llvm::Value* ptr) {
return std::pair( return std::pair(
builder.builder->CreateLoad(this->m_inner->codegen(builder), ptr), builder.builder->CreateLoad(this->m_inner->codegen(builder), ptr),
this->m_inner 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 std::string formatted() = 0;
virtual llvm::Type* codegen(codegen::Builder& builder) = 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::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 std::optional<std::shared_ptr<Type>> return_type();
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; 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) = 0; 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) = 0; 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) = 0; virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
}; };
class FundamentalType : public Type { class FundamentalType : public Type {
@ -47,7 +47,6 @@ namespace types {
virtual std::string formatted() override; virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) 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::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* 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* 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* 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 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::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 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 std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) 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::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;
}; };
} }