Commit 2a6c6696 authored by zygzagZ's avatar zygzagZ

Info na shared_ptr

parent 167d5a8c
...@@ -9,14 +9,13 @@ PIdent::PIdent(String p1, Integer p2) ...@@ -9,14 +9,13 @@ PIdent::PIdent(String p1, Integer p2)
{ {
string_ = p1; string_ = p1;
integer_ = p2; integer_ = p2;
} }
PIdent::PIdent(const PIdent & other) PIdent::PIdent(const PIdent & other)
{ {
string_ = other.string_; string_ = other.string_;
integer_ = other.integer_; integer_ = other.integer_;
var = other.var;
} }
PIdent &PIdent::operator=(const PIdent & other) PIdent &PIdent::operator=(const PIdent & other)
...@@ -30,7 +29,7 @@ void PIdent::swap(PIdent & other) ...@@ -30,7 +29,7 @@ void PIdent::swap(PIdent & other)
{ {
std::swap(string_, other.string_); std::swap(string_, other.string_);
std::swap(integer_, other.integer_); std::swap(integer_, other.integer_);
std::swap(var, other.var);
} }
PIdent::~PIdent() PIdent::~PIdent()
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include<string> #include<string>
#include<vector> #include<vector>
#include <memory>
//C++ Abstract Syntax Interface generated by the BNF Converter. //C++ Abstract Syntax Interface generated by the BNF Converter.
...@@ -340,12 +341,13 @@ public: ...@@ -340,12 +341,13 @@ public:
}; };
class VarInfo;
class PIdent : public Visitable class PIdent : public Visitable
{ {
public: public:
String string_; String string_;
Integer integer_; Integer integer_;
std::weak_ptr<VarInfo> var;
PIdent(const PIdent &); PIdent(const PIdent &);
PIdent &operator=(const PIdent &); PIdent &operator=(const PIdent &);
......
#include "Info.h" #include "Info.h"
FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass)
: VarInfo(expr->pident_, expr->type_), block(expr->block_), klass(klass)
{
arguments.reserve(expr->listarg_->size());
for (auto arg : *expr->listarg_) {
arguments.emplace_back(make_shared<VarInfo>((Ar*)arg));
}
}
ClassInfo::ClassInfo(PIdent *ident, ClassInfoPtr parent /*= nullptr*/)
: VarInfo(ident),
parent(parent),
functions(parent ? parent->functions : nullptr),
variables(parent ? parent->variables : nullptr)
{
};
Binding::Binding(shared_ptr<Binding> parent)
: variables(parent->variables),
parent(parent)
{
}
Scope::Scope()
: currentClass(nullptr)
{
}
\ No newline at end of file
...@@ -2,14 +2,27 @@ ...@@ -2,14 +2,27 @@
#define INFO_HEADER #define INFO_HEADER
#include "Absyn.h" #include "Absyn.h"
#include <memory>
#include <unordered_map>
using namespace std; using namespace std;
class VarInfo;
class FunctionInfo;
class ClassInfo;
class Binding;
class Type;
using VarInfoPtr = shared_ptr<VarInfo>;
using FunctionInfoPtr = shared_ptr<FunctionInfo>;
using ClassInfoPtr = shared_ptr<ClassInfo>;
using BindingPtr = shared_ptr<Binding>;
#include "InfoList.h"
class VarInfo { class VarInfo {
public: public:
VarInfo(string n, int l) VarInfo(string n, int l = -1, Type* type = NULL) : name(n), type(type), lineLocation(l) {}
: name(n), lineLocation(l) {} VarInfo(PIdent* ident, Type* type = NULL) : VarInfo(ident->string_, ident->integer_, type) {}
VarInfo(PIdent* ident) VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {}
: VarInfo(ident->string_, ident->integer_) {}
string name; string name;
Type *type; Type *type;
int lineLocation; int lineLocation;
...@@ -19,86 +32,43 @@ public: ...@@ -19,86 +32,43 @@ public:
} }
}; };
class ClassInfo;
class FunctionInfo : public VarInfo { class FunctionInfo : public VarInfo {
public: public:
Block * block; Block * block;
vector<VarInfo*> arguments; vector<VarInfoPtr> arguments;
ClassInfo *klass; weak_ptr<ClassInfo> klass;
FunctionInfo(PIdent *ident, ClassInfo *klass = NULL) : VarInfo(ident), klass(klass) {}; FunctionInfo(FuncDef *expr, ClassInfoPtr klass = nullptr);
~FunctionInfo() { FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
for (auto &a : arguments)
delete a;
}
}; };
class ClassInfo : public VarInfo class ClassInfo : public VarInfo
{ {
ClassInfo * parent; ClassInfoPtr parent;
public: public:
vector<FunctionInfo*> functions; InfoList<FunctionInfo> functions;
vector<VarInfo*> variables; InfoList<VarInfo> variables;
ClassInfo(PIdent *ident, ClassInfo *parent = NULL) : VarInfo(ident), parent(parent) {};
ClassInfo * getParent() const { return parent; };
FunctionInfo* getFunction(string name) const {
for (auto i : functions)
if (i->name == name)
return i;
return parent ? parent->getFunction(name) : NULL;
}
VarInfo* getVar(string name) const { ClassInfo(PIdent *ident, ClassInfoPtr parent = nullptr);
for (auto i : variables)
if (i->name == name)
return i;
return parent ? parent->getVar(name) : NULL;
}
~ClassInfo() { ClassInfoPtr getParent() const { return parent; };
for (auto &f : functions) };
delete f;
for (auto &v : variables)
delete v;
}
class Binding {
InfoList<VarInfo> variables;
BindingPtr parent;
Binding(BindingPtr parent);
}; };
class Scope { class Scope {
public: public:
vector<ClassInfo*> classes; InfoList<ClassInfo> classes;
vector<FunctionInfo*> functions; InfoList<FunctionInfo> functions;
ClassInfo *currentClass; ClassInfoPtr currentClass;
Scope();
Scope() : currentClass(NULL) {}
~Scope() {
for (auto &c : classes)
delete c;
for (auto &f : functions)
delete f;
}
ClassInfo* getClass(string name) const {
for (auto i : classes)
if (i->name == name)
return i;
return NULL;
}
FunctionInfo* getFunction(string name, bool local = false) const {
if (currentClass && !local)
if (auto *f = currentClass->getFunction(name))
return f;
for (auto i : functions)
if (i->name == name)
return i;
return NULL;
}
}; };
#endif #endif
\ No newline at end of file
#include "Info.h"
template<typename T,
typename = typename std::enable_if<std::is_base_of<VarInfo, T>::value>::type,
typename TPtr = shared_ptr<T>>
class InfoList : public unordered_map<string, TPtr> {
public:
InfoList<T> *parent;
InfoList(InfoList<T> *parent = nullptr) : parent(parent) {};
TPtr operator[](string name) const {
TPtr ret = local(name);
return ret ? ret : parent ? (*parent)[name] : nullptr;
}
TPtr local(string name) const {
auto p = (*this).find(name);
if (p != this->end()) {
return p->second;
}
return nullptr;
}
void add(TPtr obj) {
this->emplace(obj->name, obj);
}
InfoList<T>& operator<<(TPtr obj) {
add(obj);
return *this;
}
};
CC=g++ CC=g++
CCFLAGS=-g -W -Wall -O3 -std=c++1z -Wno-unused-parameter CCFLAGS=-g -W -Wall -O3 -std=c++2a -Wno-unused-parameter
FLEX=flex FLEX=flex
FLEX_OPTS=-PGrammar FLEX_OPTS=-PGrammar
...@@ -41,14 +41,14 @@ Printer.o : Printer.cpp Printer.h Absyn.h ...@@ -41,14 +41,14 @@ Printer.o : Printer.cpp Printer.h Absyn.h
Skeleton.o : Skeleton.cpp Skeleton.h Absyn.h Skeleton.o : Skeleton.cpp Skeleton.h Absyn.h
${CC} ${CCFLAGS} -Wno-unused-parameter -c Skeleton.cpp ${CC} ${CCFLAGS} -Wno-unused-parameter -c Skeleton.cpp
Latte.o : Latte.cpp Parser.h Printer.h Absyn.h ParseError.h TypeCheck.h Info.h Latte.o : Latte.cpp Parser.h Printer.h Absyn.h ParseError.h TypeCheck.h Info.h InfoList.h
${CC} ${CCFLAGS} -c Latte.cpp ${CC} ${CCFLAGS} -c Latte.cpp
TypeCheck.o : TypeCheck.cpp TypeCheck.h Info.h Absyn.h ParseError.h TypeCheck.o : TypeCheck.cpp TypeCheck.h Info.h InfoList.h Absyn.h ParseError.h
${CC} ${CCFLAGS} -c TypeCheck.cpp ${CC} ${CCFLAGS} -c TypeCheck.cpp
Info.o : Info.cpp Info.h Absyn.h Info.o : Info.cpp Info.h InfoList.h Absyn.h
${CC} ${CCFLAGS} -c Info.cpp ${CC} ${CCFLAGS} -c Info.cpp
ParseError.o : ParseError.cpp Info.h Absyn.h ParseError.h ParseError.o : ParseError.cpp Info.h InfoList.h Absyn.h ParseError.h
${CC} ${CCFLAGS} -c ParseError.cpp ${CC} ${CCFLAGS} -c ParseError.cpp
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <sstream> #include <sstream>
using namespace std; using namespace std;
RedefinedError::RedefinedError(PIdent *ident, VarInfo *orig) { RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
stringstream ss; stringstream ss;
ss << "Variable \"" << ident->string_ << "\" at line " << ident->integer_ << " redeclared! First declaration at line " << orig->lineLocation; ss << "Variable \"" << ident->string_ << "\" at line " << ident->integer_ << " redeclared! First declaration at line " << orig->lineLocation;
msg = ss.str(); msg = ss.str();
......
#ifndef ERROR_HEADER #ifndef ERROR_HEADER
#define ERROR_HEADER #define ERROR_HEADER
#include "Absyn.h" #include "Absyn.h"
#include "Info.h"
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
#include <memory> #include <memory>
...@@ -17,11 +18,10 @@ public: ...@@ -17,11 +18,10 @@ public:
}; };
class PIdent; class PIdent;
class VarInfo;
class RedefinedError : public ParseError { class RedefinedError : public ParseError {
public: public:
RedefinedError(PIdent *ident, VarInfo *orig); RedefinedError(PIdent *ident, VarInfoPtr orig);
}; };
class UndefinedError : public ParseError { class UndefinedError : public ParseError {
......
...@@ -8,20 +8,20 @@ void TypeCheck::visitFunDef(FunDef *t) {} //abstract class ...@@ -8,20 +8,20 @@ void TypeCheck::visitFunDef(FunDef *t) {} //abstract class
void TypeCheck::visitArg(Arg *t) {} //abstract class void TypeCheck::visitArg(Arg *t) {} //abstract class
void TypeCheck::visitClassDef(ClassDef *t) { void TypeCheck::visitClassDef(ClassDef *t) {
const string name = t->getName()->string_; const string name = t->getName()->string_;
ClassInfo *c = scope.getClass(name); ClassInfoPtr c = scope.classes[name];
if (c) { if (c) {
throw RedefinedError(t->getName(), c); throw RedefinedError(t->getName(), c);
} }
ClassInfo *parent = NULL; ClassInfoPtr parent = NULL;
if (t->getParent()) { if (t->getParent()) {
const string parentName = t->getParent()->string_; const string parentName = t->getParent()->string_;
parent = scope.getClass(parentName); parent = scope.classes[parentName];
if (!parent) { if (!parent) {
throw UndefinedError(t->getParent()); throw UndefinedError(t->getParent());
} }
} }
c = new ClassInfo(t->getName(), parent); c = make_shared<ClassInfo>(t->getName(), parent);
scope.classes.push_back(c); scope.classes << c;
scope.currentClass = c; scope.currentClass = c;
t->getBlock()->accept(this); t->getBlock()->accept(this);
...@@ -75,16 +75,16 @@ void TypeCheck::visitClDef(ClDef *cl_def) ...@@ -75,16 +75,16 @@ void TypeCheck::visitClDef(ClDef *cl_def)
void TypeCheck::visitFuncDef(FuncDef *def) void TypeCheck::visitFuncDef(FuncDef *def)
{ {
const string name = def->pident_->string_; const string name = def->pident_->string_;
FunctionInfo *f = scope.getFunction(name); FunctionInfoPtr f = scope.functions[name];
if (f) { if (f) {
throw RedefinedError(def->pident_, f); throw RedefinedError(def->pident_, f);
} }
f = new FunctionInfo(def->pident_, scope.currentClass); f = make_shared<FunctionInfo>(def->pident_, scope.currentClass);
f->block = def->block_; f->block = def->block_;
auto &targetVector = scope.currentClass ? scope.currentClass->functions : scope.functions; auto &targetVector = scope.currentClass ? scope.currentClass->functions : scope.functions;
targetVector.push_back(f); targetVector << f;
} }
void TypeCheck::visitAr(Ar *ar) void TypeCheck::visitAr(Ar *ar)
...@@ -546,9 +546,9 @@ void TypeCheck::visitEOr(EOr *e) ...@@ -546,9 +546,9 @@ void TypeCheck::visitEOr(EOr *e)
void TypeCheck::visitListTopDef(ListTopDef *list_top_def) void TypeCheck::visitListTopDef(ListTopDef *list_top_def)
{ {
for (ListTopDef::iterator i = list_top_def->begin() ; i != list_top_def->end() ; ++i) for (auto &i : *list_top_def)
{ {
(*i)->accept(this); i->accept(this);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment