Commit 2a6c6696 authored by zygzagZ's avatar zygzagZ

Info na shared_ptr

parent 167d5a8c
......@@ -9,14 +9,13 @@ PIdent::PIdent(String p1, Integer p2)
{
string_ = p1;
integer_ = p2;
}
PIdent::PIdent(const PIdent & other)
{
string_ = other.string_;
integer_ = other.integer_;
var = other.var;
}
PIdent &PIdent::operator=(const PIdent & other)
......@@ -30,7 +29,7 @@ void PIdent::swap(PIdent & other)
{
std::swap(string_, other.string_);
std::swap(integer_, other.integer_);
std::swap(var, other.var);
}
PIdent::~PIdent()
......
......@@ -3,6 +3,7 @@
#include<string>
#include<vector>
#include <memory>
//C++ Abstract Syntax Interface generated by the BNF Converter.
......@@ -340,12 +341,13 @@ public:
};
class VarInfo;
class PIdent : public Visitable
{
public:
String string_;
Integer integer_;
std::weak_ptr<VarInfo> var;
PIdent(const PIdent &);
PIdent &operator=(const PIdent &);
......
#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 @@
#define INFO_HEADER
#include "Absyn.h"
#include <memory>
#include <unordered_map>
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 {
public:
VarInfo(string n, int l)
: name(n), lineLocation(l) {}
VarInfo(PIdent* ident)
: VarInfo(ident->string_, ident->integer_) {}
VarInfo(string n, int l = -1, Type* type = NULL) : name(n), type(type), lineLocation(l) {}
VarInfo(PIdent* ident, Type* type = NULL) : VarInfo(ident->string_, ident->integer_, type) {}
VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {}
string name;
Type *type;
int lineLocation;
......@@ -19,86 +32,43 @@ public:
}
};
class ClassInfo;
class FunctionInfo : public VarInfo {
public:
Block * block;
vector<VarInfo*> arguments;
ClassInfo *klass;
FunctionInfo(PIdent *ident, ClassInfo *klass = NULL) : VarInfo(ident), klass(klass) {};
~FunctionInfo() {
for (auto &a : arguments)
delete a;
}
vector<VarInfoPtr> arguments;
weak_ptr<ClassInfo> klass;
FunctionInfo(FuncDef *expr, ClassInfoPtr klass = nullptr);
FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
};
class ClassInfo : public VarInfo
{
ClassInfo * parent;
ClassInfoPtr parent;
public:
vector<FunctionInfo*> functions;
vector<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;
}
InfoList<FunctionInfo> functions;
InfoList<VarInfo> variables;
VarInfo* getVar(string name) const {
for (auto i : variables)
if (i->name == name)
return i;
return parent ? parent->getVar(name) : NULL;
}
ClassInfo(PIdent *ident, ClassInfoPtr parent = nullptr);
~ClassInfo() {
for (auto &f : functions)
delete f;
ClassInfoPtr getParent() const { return parent; };
};
for (auto &v : variables)
delete v;
}
class Binding {
InfoList<VarInfo> variables;
BindingPtr parent;
Binding(BindingPtr parent);
};
class Scope {
public:
vector<ClassInfo*> classes;
vector<FunctionInfo*> functions;
ClassInfo *currentClass;
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;
}
InfoList<ClassInfo> classes;
InfoList<FunctionInfo> functions;
ClassInfoPtr currentClass;
Scope();
};
#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++
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_OPTS=-PGrammar
......@@ -41,14 +41,14 @@ Printer.o : Printer.cpp Printer.h Absyn.h
Skeleton.o : Skeleton.cpp Skeleton.h Absyn.h
${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
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
Info.o : Info.cpp Info.h Absyn.h
Info.o : Info.cpp Info.h InfoList.h Absyn.h
${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
......@@ -5,7 +5,7 @@
#include <sstream>
using namespace std;
RedefinedError::RedefinedError(PIdent *ident, VarInfo *orig) {
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
stringstream ss;
ss << "Variable \"" << ident->string_ << "\" at line " << ident->integer_ << " redeclared! First declaration at line " << orig->lineLocation;
msg = ss.str();
......
#ifndef ERROR_HEADER
#define ERROR_HEADER
#include "Absyn.h"
#include "Info.h"
#include <string>
#include <stdexcept>
#include <memory>
......@@ -17,11 +18,10 @@ public:
};
class PIdent;
class VarInfo;
class RedefinedError : public ParseError {
public:
RedefinedError(PIdent *ident, VarInfo *orig);
RedefinedError(PIdent *ident, VarInfoPtr orig);
};
class UndefinedError : public ParseError {
......
......@@ -8,20 +8,20 @@ void TypeCheck::visitFunDef(FunDef *t) {} //abstract class
void TypeCheck::visitArg(Arg *t) {} //abstract class
void TypeCheck::visitClassDef(ClassDef *t) {
const string name = t->getName()->string_;
ClassInfo *c = scope.getClass(name);
ClassInfoPtr c = scope.classes[name];
if (c) {
throw RedefinedError(t->getName(), c);
}
ClassInfo *parent = NULL;
ClassInfoPtr parent = NULL;
if (t->getParent()) {
const string parentName = t->getParent()->string_;
parent = scope.getClass(parentName);
parent = scope.classes[parentName];
if (!parent) {
throw UndefinedError(t->getParent());
}
}
c = new ClassInfo(t->getName(), parent);
scope.classes.push_back(c);
c = make_shared<ClassInfo>(t->getName(), parent);
scope.classes << c;
scope.currentClass = c;
t->getBlock()->accept(this);
......@@ -75,16 +75,16 @@ void TypeCheck::visitClDef(ClDef *cl_def)
void TypeCheck::visitFuncDef(FuncDef *def)
{
const string name = def->pident_->string_;
FunctionInfo *f = scope.getFunction(name);
FunctionInfoPtr f = scope.functions[name];
if (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_;
auto &targetVector = scope.currentClass ? scope.currentClass->functions : scope.functions;
targetVector.push_back(f);
targetVector << f;
}
void TypeCheck::visitAr(Ar *ar)
......@@ -546,9 +546,9 @@ void TypeCheck::visitEOr(EOr *e)
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