Skip to content
This repository has been archived by the owner on Nov 24, 2024. It is now read-only.

Commit

Permalink
more improvement to typechecker
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptakBhoumik committed May 29, 2022
1 parent 2b2f5c9 commit e33aec3
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@
"ios": "cpp",
"locale": "cpp",
"queue": "cpp",
"stack": "cpp"
"stack": "cpp",
"*.ipp": "cpp"
},
"mesonbuild.configureOnOpen": true
}
41 changes: 28 additions & 13 deletions Peregrine/analyzer/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,28 +109,38 @@ bool TypeChecker::visit(const ast::FunctionDefinition& node) {
}

bool TypeChecker::visit(const ast::VariableStatement& node) {
// not very proud of this
auto nonConstNode = const_cast<ast::VariableStatement&>(node);
auto& nonConstNode = const_cast<ast::VariableStatement&>(node);

node.varType()->accept(*this);
TypePtr varType = m_result;
bool defined_before=true;

{
if(node.name()->type()==ast::KAstIdentifier){
auto identifierType = m_env->get(identifierName(node.name()));
if (identifierType==std::nullopt) {
defined_before=false;
}
}
}

if (varType->category() == TypeCategory::Void) {
// inferring the type of the variable
node.value()->accept(*this);
nonConstNode.setProcessedType(m_result);
nonConstNode.setProcessedType(m_result,defined_before);
varType = m_result;
} else {
check(node.value(), *varType);
nonConstNode.setProcessedType(varType);
nonConstNode.setProcessedType(varType,defined_before);
}

//TODO:Check if it is an identifier
m_env->set(identifierName(node.name()), varType);
return true;
}

bool TypeChecker::visit(const ast::ConstDeclaration& node) {
auto nonConstNode = const_cast<ast::ConstDeclaration&>(node);
auto& nonConstNode = const_cast<ast::ConstDeclaration&>(node);

node.constType()->accept(*this);
TypePtr constType = m_result;
Expand Down Expand Up @@ -235,9 +245,7 @@ bool TypeChecker::visit(const ast::ListLiteral& node) {
for (auto& elem : node.elements()) {
check(elem, *listType);
}

m_result =
TypeProducer::list(listType, std::to_string(node.elements().size()));
m_result = TypeProducer::list(listType, std::to_string(node.elements().size()));
return true;
}

Expand Down Expand Up @@ -307,6 +315,7 @@ bool TypeChecker::visit(const ast::IdentifierExpression& node) {
if (!identifierType ||
identifierType.value()->category() == TypeCategory::UserDefined) {
add_error(node.token(), "undeclared identifier: " + node.value());
return true;
}

m_result = identifierType.value();
Expand All @@ -333,12 +342,18 @@ bool TypeChecker::visit(const ast::TypeExpression& node) {
bool TypeChecker::visit(const ast::ListTypeExpr& node) {
node.elemType()->accept(*this);
auto listType = m_result;

check(node.size(), *TypeProducer::integer());

if(node.size()->type()!=ast::KAstNoLiteral){
check(node.size(), *TypeProducer::integer());
}
std::string size="";
if(node.size()->type()==ast::KAstNoLiteral){
size = "-1";
}
else{
size = std::dynamic_pointer_cast<ast::IntegerLiteral>(node.size())->value();
}
m_result = TypeProducer::list(
listType,
std::dynamic_pointer_cast<ast::IntegerLiteral>(node.size())->value());
listType,size);
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion Peregrine/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,11 @@ types::TypePtr VariableStatement::processedType() const {
return m_processedType;
}

void VariableStatement::setProcessedType(types::TypePtr processedType) {
void VariableStatement::setProcessedType(types::TypePtr processedType,bool defined_before) {
m_processedType = processedType;
if(!defined_before){
m_type=m_processedType->getTypeAst();
}
}

Token VariableStatement::token() const { return m_token; }
Expand Down
3 changes: 1 addition & 2 deletions Peregrine/ast/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <string>
#include <string_view>
#include <vector>

namespace ast {

enum AstKind {
Expand Down Expand Up @@ -524,7 +523,7 @@ class VariableStatement : public AstNode {
AstNodePtr value() const;

types::TypePtr processedType() const;
void setProcessedType(types::TypePtr processedType);
void setProcessedType(types::TypePtr processedType,bool defined_before=false);

Token token() const;
AstKind type() const;
Expand Down
106 changes: 95 additions & 11 deletions Peregrine/ast/types.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "types.hpp"
#include "lexer/tokens.hpp"
#include "ast.hpp"

#include <memory>

Expand Down Expand Up @@ -115,6 +116,32 @@ bool IntType::operator==(const Type& type) const {
return false;
}

ast::AstNodePtr IntType::getTypeAst() const {
std::string res;
if(m_modifier==Modifier::Unsigned)
res = "u";
else
res = "i";
switch (m_intSize) {
case IntType::Int8:
res += "8";
break;
case IntType::Int16:
res += "16";
break;
case IntType::Int32:
res += "32";
break;
case IntType::Int64:
if(m_modifier==Modifier::Unsigned)
res = "uint";
else
res = "int";
break;
}
return std::make_shared<ast::TypeExpression>((Token){}, res);
}

DecimalType::DecimalType(DecimalSize decimalSize) {
m_decimalSize = decimalSize;
}
Expand Down Expand Up @@ -157,11 +184,32 @@ bool DecimalType::isCastableTo(const Type& type) const {
}

std::string DecimalType::stringify() const {
return (isFloat()) ? "float" : "double";
if(m_decimalSize==DecimalSize::Float64)
return "float";
else if(m_decimalSize==DecimalSize::Float32)
return "f32";
else
return "f128";
}

ast::AstNodePtr DecimalType::getTypeAst() const {
std::string res;
switch (m_decimalSize) {
case DecimalSize::Float64:
res += "float";
break;
case DecimalSize::Float32:
res += "f32";
break;
case DecimalSize::Float128:
res += "f128";
break;
}
return std::make_shared<ast::TypeExpression>((Token){}, res);
}

bool DecimalType::isFloat() const {
return (m_decimalSize == DecimalSize::Float);
return (m_decimalSize == DecimalSize::Float64);
}

TypePtr DecimalType::prefixOperatorResult(Token op) const {
Expand Down Expand Up @@ -264,6 +312,9 @@ TypePtr StringType::infixOperatorResult(Token op, const TypePtr type) const {
return nullptr;
}
}
ast::AstNodePtr StringType::getTypeAst() const {
return std::make_shared<ast::TypeExpression>((Token){}, "str");
}

TypeCategory BoolType::category() const { return TypeCategory::Bool; }

Expand Down Expand Up @@ -293,6 +344,10 @@ bool BoolType::isCastableTo(const Type& type) const {

std::string BoolType::stringify() const { return "bool"; }

ast::AstNodePtr BoolType::getTypeAst() const {
return std::make_shared<ast::TypeExpression>((Token){}, "bool");
}

PointerType::PointerType(TypePtr baseType) { m_baseType = baseType; }

TypeCategory PointerType::category() const { return TypeCategory::Pointer; }
Expand Down Expand Up @@ -352,6 +407,10 @@ TypePtr PointerType::infixOperatorResult(Token op, const TypePtr type) const {
return nullptr;
}

ast::AstNodePtr PointerType::getTypeAst() const {
return std::make_shared<ast::PointerTypeExpr>((Token){}, m_baseType->getTypeAst());
}

TypeCategory VoidType::category() const { return TypeCategory::Void; }

bool VoidType::isConvertibleTo(const Type& type) const { return false; }
Expand All @@ -360,6 +419,10 @@ bool VoidType::isCastableTo(const Type& type) const { return false; }

std::string VoidType::stringify() const { return "void"; }

ast::AstNodePtr VoidType::getTypeAst() const {
return std::make_shared<ast::TypeExpression>((Token){}, "void");
}

ListType::ListType(TypePtr elemType, std::string size) {
m_elemType = elemType;
m_size = size;
Expand Down Expand Up @@ -412,12 +475,23 @@ bool ListType::operator==(const Type& type) const {

auto listType = dynamic_cast<const ListType&>(type);
if (m_elemType->operator==(*listType.elemType()) &&
m_size == listType.size())
(m_size == listType.size()||listType.size() == "-1"))
return true;

return false;
}

ast::AstNodePtr ListType::getTypeAst() const {
ast::AstNodePtr size;
if(m_size=="-1"){
size=std::make_shared<ast::NoLiteral>();
}
else{
size=std::make_shared<ast::IntegerLiteral>((Token){}, m_size);
}
return std::make_shared<ast::ListTypeExpr>((Token){}, m_elemType->getTypeAst(),size);
}

UserDefinedType::UserDefinedType(TypePtr baseType) { m_baseType = baseType; }

TypeCategory UserDefinedType::category() const {
Expand All @@ -435,14 +509,18 @@ bool UserDefinedType::isCastableTo(const Type& type) const {
}

// TODO
std::string UserDefinedType::stringify() const { return ""; }
std::string UserDefinedType::stringify() const { return m_baseType->stringify(); }

bool UserDefinedType::operator==(const Type& type) const {
if (m_baseType->operator==(type))
return true;
return false;
}

ast::AstNodePtr UserDefinedType::getTypeAst() const {
return m_baseType->getTypeAst();
}

FunctionType::FunctionType(std::vector<TypePtr> parameterTypes,
TypePtr returnType) {
m_parameterTypes = parameterTypes;
Expand Down Expand Up @@ -484,6 +562,13 @@ bool FunctionType::isCastableTo(const Type& type) const { return false; }

std::string FunctionType::stringify() const { return "function"; }

ast::AstNodePtr FunctionType::getTypeAst() const {
std::vector<ast::AstNodePtr> params;
for (auto& paramType : m_parameterTypes)
params.push_back(paramType->getTypeAst());
return std::make_shared<ast::FunctionTypeExpr>((Token){},params, m_returnType->getTypeAst());
}

bool FunctionType::operator==(const Type& type) const {
if (type.category() != TypeCategory::Function)
return false;
Expand Down Expand Up @@ -515,9 +600,10 @@ std::array<TypePtr, 8> TypeProducer::m_integer = {
std::make_shared<IntType>(IntType::IntSizes::Int64,
IntType::Modifier::Unsigned)};

std::array<TypePtr, 2> TypeProducer::m_decimal = {
std::make_shared<DecimalType>(DecimalType::DecimalSize::Float),
std::make_shared<DecimalType>(DecimalType::DecimalSize::Double)};
std::array<TypePtr, 3> TypeProducer::m_decimal = {
std::make_shared<DecimalType>(DecimalType::DecimalSize::Float64),
std::make_shared<DecimalType>(DecimalType::DecimalSize::Float32),
std::make_shared<DecimalType>(DecimalType::DecimalSize::Float128)};

TypePtr TypeProducer::m_bool = std::make_shared<BoolType>();
TypePtr TypeProducer::m_string = std::make_shared<StringType>();
Expand Down Expand Up @@ -555,7 +641,6 @@ std::map<std::string, TypePtr> identifierToTypeMap = {
{"i16", TypeProducer::integer(IntType::IntSizes::Int16)},
{"i32", TypeProducer::integer()},
{"int", TypeProducer::integer()},
{"i64", TypeProducer::integer(IntType::IntSizes::Int64)},
{"u8", TypeProducer::integer(IntType::IntSizes::Int8,
IntType::Modifier::Unsigned)},
{"u16", TypeProducer::integer(IntType::IntSizes::Int16,
Expand All @@ -564,10 +649,9 @@ std::map<std::string, TypePtr> identifierToTypeMap = {
IntType::Modifier::Unsigned)},
{"uint", TypeProducer::integer(IntType::IntSizes::Int32,
IntType::Modifier::Unsigned)},
{"u64", TypeProducer::integer(IntType::IntSizes::Int64,
IntType::Modifier::Unsigned)},
{"float", TypeProducer::decimal()},
{"double", TypeProducer::decimal(DecimalType::DecimalSize::Double)},
{"f32", TypeProducer::decimal(DecimalType::DecimalSize::Float32)},
{"f128", TypeProducer::decimal(DecimalType::DecimalSize::Float128)},
{"str", TypeProducer::string()},
{"bool", TypeProducer::boolean()},
{"void", TypeProducer::voidT()}};
Expand Down
Loading

0 comments on commit e33aec3

Please sign in to comment.