Compare commits
5 Commits
db8de8fc30
...
8d64416b5e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d64416b5e | |||
| e064b3f04d | |||
| adc74333ff | |||
| 2223b4a6a5 | |||
| 2034c6c55f |
@ -6,6 +6,7 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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::Int}
|
new types::FundamentalType{true, types::FundamentalTypeKind::AnyInt}
|
||||||
} } } {
|
} } } {
|
||||||
}
|
}
|
||||||
virtual ~IntLiteralExpression() override = default;
|
virtual ~IntLiteralExpression() override = default;
|
||||||
|
|||||||
@ -7,13 +7,33 @@ 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 : { int_ty, char_ty, bool_ty }) {
|
for (auto& 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) {
|
||||||
@ -107,13 +127,32 @@ 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 : { int_ty, char_ty }) {
|
for (auto& 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) {
|
||||||
@ -168,7 +207,11 @@ namespace types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not & Negation
|
// Not & Negation
|
||||||
for (auto& ty : { int_ty, char_ty, bool_ty }) {
|
for (auto& 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) {
|
||||||
|
|||||||
@ -8,12 +8,41 @@ 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 = { int_ty, char_ty, bool_ty };
|
auto numerical_types = {
|
||||||
|
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) {
|
||||||
|
|||||||
@ -782,12 +782,24 @@ 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:
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "parsing.h"
|
#include "parsing.h"
|
||||||
#include "tokens.h"
|
#include "tokens.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace parsing {
|
namespace parsing {
|
||||||
namespace {
|
namespace {
|
||||||
@ -126,16 +127,64 @@ 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 = token.content;
|
std::string type_name = {};
|
||||||
|
|
||||||
if (type_name == "int") {
|
std::set<std::string> type_parts = { "unsigned", "short", "long", "int", "char", "void" };
|
||||||
|
|
||||||
|
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 };
|
||||||
|
|||||||
@ -118,7 +118,15 @@ 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;
|
||||||
}
|
}
|
||||||
@ -216,6 +224,10 @@ 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 };
|
||||||
}
|
}
|
||||||
@ -224,11 +236,39 @@ 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) {
|
||||||
@ -239,6 +279,8 @@ 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);
|
||||||
|
|||||||
@ -46,12 +46,39 @@ 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;
|
||||||
@ -80,10 +107,21 @@ 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::Bool:
|
case FundamentalTypeKind::UShortInt:
|
||||||
|
case FundamentalTypeKind::UInt:
|
||||||
|
case FundamentalTypeKind::ULongInt:
|
||||||
|
case FundamentalTypeKind::ULongLongInt:
|
||||||
|
return false;
|
||||||
case FundamentalTypeKind::Char:
|
case FundamentalTypeKind::Char:
|
||||||
|
return true;
|
||||||
|
case FundamentalTypeKind::UChar:
|
||||||
|
return false;
|
||||||
|
case FundamentalTypeKind::Bool:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid type");
|
throw std::runtime_error("Invalid type");
|
||||||
@ -92,11 +130,22 @@ 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");
|
||||||
|
|||||||
13
src/types.h
13
src/types.h
@ -17,8 +17,21 @@ 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
8
test.c
@ -25,7 +25,7 @@ void update_ptr(char* ptr) {
|
|||||||
*ptr = 50;
|
*ptr = 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
long long 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,5 +71,9 @@ int main() {
|
|||||||
printf("while-counter: %d\n", counter++);
|
printf("while-counter: %d\n", counter++);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
short int sh = 123 + 5;
|
||||||
|
long int lg = 456;
|
||||||
|
long long int longer = 789;
|
||||||
|
|
||||||
|
return sh;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user