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

Commit

Permalink
fix add union tyoe
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptakBhoumik committed Jun 21, 2022
1 parent a1b081f commit 98a8b68
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 9 deletions.
15 changes: 9 additions & 6 deletions Peregrine/analyzer/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,9 @@ bool TypeChecker::visit(const ast::DotExpression& node) {
if(node.owner()->type()==ast::KAstIdentifier&&node.referenced()->type()==ast::KAstIdentifier){
auto name=identifierName(node.owner());
auto ref=identifierName(node.referenced());
if(m_enumMap.contains(name)){
auto type=m_enumMap[name];
auto enum_map=m_env->getEnumMap();
if(enum_map.contains(name)){
auto type=enum_map[name];
auto _enum=std::dynamic_pointer_cast<types::EnumType>(type);
auto items=_enum->getItem();
if(std::count(items.begin(),items.end(),ref)){
Expand Down Expand Up @@ -458,8 +459,9 @@ bool TypeChecker::visit(const ast::IdentifierExpression& node) {
}

bool TypeChecker::visit(const ast::TypeExpression& node) {
if(m_enumMap.contains(node.value())){
m_result=m_enumMap[node.value()];
auto enum_map = m_env->getEnumMap();
if(enum_map.contains(node.value())){
m_result=enum_map[node.value()];
}
else if (!identifierToTypeMap.count(node.value())) {
auto type = m_env->get(node.value());
Expand Down Expand Up @@ -580,11 +582,12 @@ bool TypeChecker::visit(const ast::EnumLiteral& node) {
values.push_back(itemName);
}
}
if(m_enumMap.contains(name)){
auto enum_map= m_env->getEnumMap();
if(enum_map.contains(name)){
add_error(node.token(), "Redefination of enum: " + name);
}
else{
m_enumMap[name] = types::TypeProducer::enumT(name, values);
m_env->add_enum(name,types::TypeProducer::enumT(name, values));
}
return true;
}
Expand Down
1 change: 0 additions & 1 deletion Peregrine/analyzer/typeChecker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ class TypeChecker : public ast::AstVisitor {

// the function whose body is being currently checked
std::shared_ptr<FunctionType> m_currentFunction;
std::map<std::string, TypePtr> m_enumMap;//TODO:Nested enum
TypePtr m_returnType=NULL;//current return type
};
}
Expand Down
72 changes: 70 additions & 2 deletions Peregrine/ast/types.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//TODO: handle user defined types like `type name=int` properly
//int==user_defined_type
//should be checked properly
#include "types.hpp"
#include "lexer/tokens.hpp"
#include "ast.hpp"
Expand Down Expand Up @@ -400,7 +402,7 @@ bool PointerType::isCastableTo(const Type& type) const {
switch (type.category()) {
case TypeCategory::UserDefined:
case TypeCategory::Integer:
case TypeCategory::Pointer:
case TypeCategory::Pointer://TODO:Check if it inherits from the same basetype
break;

default:
Expand Down Expand Up @@ -776,11 +778,77 @@ std::string EnumType::getCurrValue() const{
bool EnumType::operator==(const Type& type) const{
if(type.category()==TypeCategory::Enum){
auto& enumType=dynamic_cast<const EnumType&>(type);
return m_name==enumType.getName();
auto item=enumType.getItem();
if(m_name==enumType.getName()&&item.size()==m_items.size()){
for(size_t i=0; i<m_items.size();++i){
if(m_items[i]!=item[i]){
return false;
}
}
return true;
}
}
return false;
}

UnionTypeDef::UnionTypeDef(std::string name,std::map<std::string,TypePtr> items){
m_name=name;
m_items=items;
}

ast::AstNodePtr UnionTypeDef::getTypeAst() const{
return std::make_shared<ast::TypeExpression>((Token){},m_name.c_str());
}

TypeCategory UnionTypeDef::category() const{
return TypeCategory::Union;
}

bool UnionTypeDef::isConvertibleTo(const Type& type) const{
return false;
}

bool UnionTypeDef::isCastableTo(const Type& type) const{
switch(type.category()){
case TypeCategory::Pointer:
return true;
default:
return false;
}
}

std::string UnionTypeDef::stringify() const{
return m_name;
}

std::map<std::string,TypePtr> UnionTypeDef::getItem() const{
return m_items;
}

std::string UnionTypeDef::getName() const{
return m_name;
}

bool UnionTypeDef::operator==(const Type& type) const{
if(type.category() == TypeCategory::Union){
auto& unionType=dynamic_cast<const UnionTypeDef&>(type);
auto items=unionType.getItem();
if(m_name==unionType.getName()&&items.size()==m_items.size()){
for(auto& item : items){
if(m_items.contains(item.first)){
auto pos = m_items.find(item.first);
if(pos->second!=item.second){
return false;
}
}
else{
return false;
}
}
}
}
return false;
}

std::array<TypePtr, 8> TypeProducer::m_integer = {
std::make_shared<IntType>(IntType::IntSizes::Int8),
Expand Down
19 changes: 19 additions & 0 deletions Peregrine/ast/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum TypeCategory {
MultipleReturn,
Enum,
Void,
Union
};

class Type;
Expand Down Expand Up @@ -283,6 +284,24 @@ class EnumType : public Type {
std::string m_name;
};

class UnionTypeDef : public Type {
public:
UnionTypeDef(std::string name,std::map<std::string,TypePtr> items);

ast::AstNodePtr getTypeAst() const;
TypeCategory category() const;
bool isConvertibleTo(const Type& type) const;
bool isCastableTo(const Type& type) const;
std::string stringify() const;
std::map<std::string,TypePtr> getItem() const;
std::string getName() const;

bool operator==(const Type& type) const;
private:
std::map<std::string,TypePtr> m_items;
std::string m_name;
};

class TypeProducer {
static std::array<TypePtr, 8> m_integer;
static std::array<TypePtr, 3> m_decimal;
Expand Down
12 changes: 12 additions & 0 deletions Peregrine/utils/symbolTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ template<typename T>
class SymbolTable {
std::map<std::string, T> m_symbols;
std::shared_ptr<SymbolTable<T>> m_parent;
std::map<std::string, T> m_enumMap;

public:
SymbolTable(std::shared_ptr<SymbolTable> parent) {
m_parent = parent;
if(m_parent!=nullptr){
m_enumMap = parent->getEnumMap();
}
}

std::optional<T> get(std::string name) {
Expand All @@ -33,6 +37,14 @@ class SymbolTable {
return m_symbols[name];
}

std::map<std::string, T> getEnumMap(){
return m_enumMap;
}

void add_enum(std::string key,T value){
m_enumMap[key]=value;
}

bool set(std::string name, T value) {
if (get(name)) {
return false; // the symbol has been defined already
Expand Down

0 comments on commit 98a8b68

Please sign in to comment.