Compare commits

..

No commits in common. "8d64416b5e3b3dcfcd6f9488a0e423da88ad461b" and "db8de8fc30ba90000174df33a1e6d53a8bc57d9e" have entirely different histories.

10 changed files with 10 additions and 252 deletions

View File

@ -6,7 +6,6 @@ namespace AST {
std::string IntLiteralExpression::formatted() { std::string IntLiteralExpression::formatted() {
std::stringstream out{ "" }; std::stringstream out{ "" };
out << this->m_value; out << this->m_value;
out << this->m_ty->formatted();
return out.str(); return out.str();
} }

View File

@ -55,7 +55,7 @@ namespace AST {
: Expression{ meta } : Expression{ meta }
, m_value{ value } , m_value{ value }
, m_ty{ { std::shared_ptr<types::Type>{ , m_ty{ { std::shared_ptr<types::Type>{
new types::FundamentalType{true, types::FundamentalTypeKind::AnyInt} new types::FundamentalType{true, types::FundamentalTypeKind::Int}
} } } { } } } {
} }
virtual ~IntLiteralExpression() override = default; virtual ~IntLiteralExpression() override = default;

View File

@ -7,33 +7,13 @@ namespace types {
auto int_ty = std::shared_ptr<types::Type>{ auto int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Int } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
auto uint_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UInt } };
auto char_ty = std::shared_ptr<types::Type>{ auto char_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Char } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
auto uchar_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UChar } };
auto short_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ShortInt } };
auto ushort_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UShortInt } };
auto long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::LongInt } };
auto ulong_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongInt } };
auto long_long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::LongLongInt } };
auto ulong_long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongLongInt } };
auto bool_ty = std::shared_ptr<types::Type>{ auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
// Integer arithmetic binops // Integer arithmetic binops
for (auto& ty : { for (auto& ty : { int_ty, char_ty, bool_ty }) {
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
bool_ty
}) {
definitions.push_back(BinopDefinition{ definitions.push_back(BinopDefinition{
ty, types::BinOp::Add, ty, ty, types::BinOp::Add, ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
@ -127,32 +107,13 @@ namespace types {
auto int_ty = std::shared_ptr<types::Type>{ auto int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Int } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
auto uint_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UInt } };
auto char_ty = std::shared_ptr<types::Type>{ auto char_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Char } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
auto uchar_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UChar } };
auto short_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ShortInt } };
auto ushort_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::UShortInt } };
auto long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::LongInt } };
auto ulong_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongInt } };
auto long_long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::LongLongInt } };
auto ulong_long_int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongLongInt } };
auto bool_ty = std::shared_ptr<types::Type>{ auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
// Integer Increment/Decrement unaries // Integer Increment/Decrement unaries
for (auto& ty : { for (auto& ty : { int_ty, char_ty }) {
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
}) {
definitions.push_back(UnopDefinition{ definitions.push_back(UnopDefinition{
ty, types::Unary::AddPostfix, ty, ty, types::Unary::AddPostfix, ty,
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* ptr) { [](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* ptr) {
@ -207,11 +168,7 @@ namespace types {
} }
// Not & Negation // Not & Negation
for (auto& ty : { for (auto& ty : { int_ty, char_ty, bool_ty }) {
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
bool_ty
}) {
definitions.push_back(UnopDefinition{ definitions.push_back(UnopDefinition{
ty, types::Unary::Not, ty, ty, types::Unary::Not, ty,
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* value) { [](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* value) {

View File

@ -8,41 +8,12 @@ namespace types {
auto int_ty = std::shared_ptr<Type>{ auto int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::Int } }; new FundamentalType{ false, FundamentalTypeKind::Int } };
auto uint_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::UInt } };
auto char_ty = std::shared_ptr<Type>{ auto char_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::Char } }; new FundamentalType{ false, FundamentalTypeKind::Char } };
auto uchar_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::UChar } };
auto short_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::ShortInt } };
auto ushort_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::UShortInt } };
auto long_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::LongInt } };
auto ulong_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::ULongInt } };
auto long_long_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::LongLongInt } };
auto ulong_long_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::ULongLongInt } };
auto bool_ty = std::shared_ptr<Type>{ auto bool_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::Bool } }; new FundamentalType{ false, FundamentalTypeKind::Bool } };
auto any_int_ty = std::shared_ptr<Type>{
new FundamentalType{ false, FundamentalTypeKind::AnyInt } };
auto numerical_types = { auto numerical_types = { int_ty, char_ty, bool_ty };
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
bool_ty
};
for (auto& target_ty : numerical_types) {
casts.push_back(CastDefinition{ any_int_ty, target_ty, true,
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* value) {
return value;
} });
}
for (auto& source_ty : numerical_types) { for (auto& source_ty : numerical_types) {
for (auto& target_ty : numerical_types) { for (auto& target_ty : numerical_types) {

View File

@ -782,24 +782,12 @@ namespace AST {
namespace types { namespace types {
llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::TypeMap&) { llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::TypeMap&) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::ShortInt:
case FundamentalTypeKind::UShortInt:
return builder.builder->getInt16Ty();
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::UInt:
return builder.builder->getInt32Ty(); return builder.builder->getInt32Ty();
case FundamentalTypeKind::LongInt:
case FundamentalTypeKind::ULongInt:
return builder.builder->getInt64Ty();
case FundamentalTypeKind::LongLongInt:
case FundamentalTypeKind::ULongLongInt:
return builder.builder->getInt128Ty();
case FundamentalTypeKind::Bool: case FundamentalTypeKind::Bool:
return builder.builder->getInt1Ty(); return builder.builder->getInt1Ty();
case FundamentalTypeKind::Char: case FundamentalTypeKind::Char:
return builder.builder->getInt8Ty(); return builder.builder->getInt8Ty();
case FundamentalTypeKind::UChar:
return builder.builder->getInt8Ty();
case FundamentalTypeKind::Void: case FundamentalTypeKind::Void:
return builder.builder->getVoidTy(); return builder.builder->getVoidTy();
default: default:

View File

@ -2,7 +2,6 @@
#include "parsing.h" #include "parsing.h"
#include "tokens.h" #include "tokens.h"
#include <set>
namespace parsing { namespace parsing {
namespace { namespace {
@ -127,64 +126,16 @@ namespace parsing {
} }
else { else {
// TODO eventually make this be potentially more than one word // TODO eventually make this be potentially more than one word
std::string type_name = {}; std::string type_name = token.content;
std::set<std::string> type_parts = { "unsigned", "short", "long", "int", "char", "void" }; if (type_name == "int") {
int counter = 0;
while (token.type == token::Type::Ident && type_parts.contains(token.content)) {
if (counter > 0) {
type_name += " ";
inner.next();
}
type_name += token.content;
counter++;
token = inner.peek();
}
std::cout << type_name << std::endl;
if (type_name == "short int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::ShortInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "unsigned short int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::UShortInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Int }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Int };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else if (type_name == "unsigned int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::UInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "long int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::LongInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "unsigned long int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::ULongInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "long long int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::LongLongInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "unsigned long long int") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::ULongLongInt };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "char") { else if (type_name == "char") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Char }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Char };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else if (type_name == "unsigned char") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::UChar };
returned = std::shared_ptr<types::Type>{ ty };
}
else if (type_name == "void") { else if (type_name == "void") {
auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Void }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Void };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };

View File

@ -118,15 +118,7 @@ namespace AST {
if ( if (
ty->m_ty == types::FundamentalTypeKind::Bool ty->m_ty == types::FundamentalTypeKind::Bool
|| ty->m_ty == types::FundamentalTypeKind::Char || ty->m_ty == types::FundamentalTypeKind::Char
|| ty->m_ty == types::FundamentalTypeKind::UChar
|| ty->m_ty == types::FundamentalTypeKind::ShortInt
|| ty->m_ty == types::FundamentalTypeKind::UShortInt
|| ty->m_ty == types::FundamentalTypeKind::Int || ty->m_ty == types::FundamentalTypeKind::Int
|| ty->m_ty == types::FundamentalTypeKind::UInt
|| ty->m_ty == types::FundamentalTypeKind::LongInt
|| ty->m_ty == types::FundamentalTypeKind::ULongInt
|| ty->m_ty == types::FundamentalTypeKind::LongLongInt
|| ty->m_ty == types::FundamentalTypeKind::ULongLongInt
) { ) {
this->m_ty = *expected_ty; this->m_ty = *expected_ty;
} }
@ -224,10 +216,6 @@ namespace AST {
if (!rhs_res.ok()) if (!rhs_res.ok())
// Skip if not implicitly castable to lhs // Skip if not implicitly castable to lhs
continue; continue;
rhs_ty = this->m_rhs->typecheck(state, scope, binop.rhs).type;
rhs_res = check_type(state, rhs_ty, binop.rhs);
this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state); this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false }; return { binop.result(binop, lhs_ty, rhs_ty), false, false };
} }
@ -236,39 +224,11 @@ namespace AST {
if (!lhs_res.ok()) if (!lhs_res.ok())
// Skip if not implicitly castable to rhs // Skip if not implicitly castable to rhs
continue; continue;
lhs_ty = this->m_lhs->typecheck(state, scope, binop.lhs).type;
lhs_res = check_type(state, lhs_ty, binop.lhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state); this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false }; return { binop.result(binop, lhs_ty, rhs_ty), false, false };
} }
} }
// if that fails, accept binops that match the result type perfectly and
// is able to cast both types successfully
for (auto& binop : state.binops) {
if (expected_ty) {
// Skip any binops that would not be immediately assignable to
// the expected type
if (!types::types_equal(binop.result(binop, lhs_ty, rhs_ty), *expected_ty)) {
continue;
}
}
auto rhs_res = check_type(state, rhs_ty, binop.rhs);
auto lhs_res = check_type(state, lhs_ty, binop.lhs);
if (!rhs_res.ok() || !lhs_res.ok())
continue;
lhs_ty = this->m_lhs->typecheck(state, scope, binop.lhs).type;
rhs_ty = this->m_rhs->typecheck(state, scope, binop.rhs).type;
lhs_res = check_type(state, lhs_ty, binop.lhs);
rhs_res = check_type(state, rhs_ty, binop.rhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state);
this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false };
}
// Finally check for any binop that allows the result to be implicitly // Finally check for any binop that allows the result to be implicitly
// casted to the result // casted to the result
for (auto& binop : state.binops) { for (auto& binop : state.binops) {
@ -279,8 +239,6 @@ namespace AST {
if (!result_res.ok()) if (!result_res.ok())
continue; continue;
} }
lhs_ty = this->m_lhs->typecheck(state, scope, binop.lhs).type;
rhs_ty = this->m_rhs->typecheck(state, scope, binop.rhs).type;
auto lhs_result = check_type(state, lhs_ty, binop.lhs); auto lhs_result = check_type(state, lhs_ty, binop.lhs);
auto rhs_result = check_type(state, rhs_ty, binop.rhs); auto rhs_result = check_type(state, rhs_ty, binop.rhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_result, state); this->m_lhs = handle_res(std::move(this->m_lhs), lhs_result, state);

View File

@ -46,39 +46,12 @@ namespace types {
if (this->m_const) if (this->m_const)
out << "const "; out << "const ";
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::ShortInt:
out << "ShortInt";
break;
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
out << "Int"; out << "Int";
break; break;
case FundamentalTypeKind::LongInt:
out << "LongInt";
break;
case FundamentalTypeKind::LongLongInt:
out << "LongLongInt";
break;
case FundamentalTypeKind::UShortInt:
out << "UShortInt";
break;
case FundamentalTypeKind::UInt:
out << "UInt";
break;
case FundamentalTypeKind::ULongInt:
out << "ULongInt";
break;
case FundamentalTypeKind::ULongLongInt:
out << "ULongLongInt";
break;
case FundamentalTypeKind::AnyInt:
out << "AnyInt";
break;
case FundamentalTypeKind::Bool: case FundamentalTypeKind::Bool:
out << "Bool"; out << "Bool";
break; break;
case FundamentalTypeKind::UChar:
out << "UChar";
break;
case FundamentalTypeKind::Char: case FundamentalTypeKind::Char:
out << "Char"; out << "Char";
break; break;
@ -107,21 +80,10 @@ namespace types {
bool FundamentalType::is_signed() { bool FundamentalType::is_signed() {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::ShortInt:
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::LongInt:
case FundamentalTypeKind::LongLongInt:
return true; return true;
case FundamentalTypeKind::UShortInt:
case FundamentalTypeKind::UInt:
case FundamentalTypeKind::ULongInt:
case FundamentalTypeKind::ULongLongInt:
return false;
case FundamentalTypeKind::Char:
return true;
case FundamentalTypeKind::UChar:
return false;
case FundamentalTypeKind::Bool: case FundamentalTypeKind::Bool:
case FundamentalTypeKind::Char:
return false; return false;
default: default:
throw std::runtime_error("Invalid type"); throw std::runtime_error("Invalid type");
@ -130,22 +92,11 @@ namespace types {
uint32_t FundamentalType::size() { uint32_t FundamentalType::size() {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::ShortInt:
case FundamentalTypeKind::UShortInt:
return 16;
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
case FundamentalTypeKind::UInt:
return 32; return 32;
case FundamentalTypeKind::LongInt:
case FundamentalTypeKind::ULongInt:
return 64;
case FundamentalTypeKind::LongLongInt:
case FundamentalTypeKind::ULongLongInt:
return 128;
case FundamentalTypeKind::Bool: case FundamentalTypeKind::Bool:
return 1; return 1;
case FundamentalTypeKind::Char: case FundamentalTypeKind::Char:
case FundamentalTypeKind::UChar:
return 8; return 8;
default: default:
throw std::runtime_error("Invalid type"); throw std::runtime_error("Invalid type");

View File

@ -17,21 +17,8 @@ namespace types {
enum FundamentalTypeKind { enum FundamentalTypeKind {
Int, Int,
ShortInt,
LongInt,
LongLongInt,
UInt,
UShortInt,
ULongInt,
ULongLongInt,
/// @brief stand-in type for integer literals
AnyInt,
Bool, Bool,
Char, Char,
UChar,
Void, Void,
/// @brief Mainly used for binop resolution /// @brief Mainly used for binop resolution
Any, Any,

8
test.c
View File

@ -25,7 +25,7 @@ void update_ptr(char* ptr) {
*ptr = 50; *ptr = 50;
} }
long long int main() { int main() {
// Test fibonacci sequence // Test fibonacci sequence
char text[30] = "10th fibonacci number is %d!\n"; char text[30] = "10th fibonacci number is %d!\n";
printf(text, fibonacci(10)); printf(text, fibonacci(10));
@ -71,9 +71,5 @@ long long int main() {
printf("while-counter: %d\n", counter++); printf("while-counter: %d\n", counter++);
} }
short int sh = 123 + 5; return 0;
long int lg = 456;
long long int longer = 789;
return sh;
} }