Commit 5d4e9753 authored by Sarah Spall's avatar Sarah Spall Committed by Vikram Narayanan

visitor that allocates each type

parent f717bed6
#include "lcd_ast.h"
CCSTStatement* AllocateTypeVisitor::visit(Typedef *td, Variable *v)
{
return allocation_helper(td->type(), v, 0);
}
CCSTStatement* AllocateTypeVisitor::visit(VoidType *vt, Variable *v)
{
return allocation_helper(vt, v, 0);
}
CCSTStatement* AllocateTypeVisitor::visit(IntegerType *it, Variable *v)
{
return allocation_helper(it, v, 0);
}
CCSTStatement* AllocateTypeVisitor::visit(PointerType *pt, Variable *v)
{
// count pointers.
// get inner type
Type *t = first_non_pointer(pt);
switch(t->num()) {
case 1: { // typedef
Typedef *td = dynamic_cast<Typedef*>(t);
Assert(td != 0x0, "Error: dynamic cast failed!\n");
return allocation_helper(td, v, count_pointers(pt));
}
case 2: { // integer type
IntegerType *it = dynamic_cast<IntegerType*>(t);
Assert(it != 0x0, "Error: dynamic cast failed!\n");
return allocation_helper(it, v, count_pointers(pt));
}
case 3: {
Assert(1 == 0, "Error: this should not happen!\n");
}
case 4: { // projection type
ProjectionType *proj = dynamic_cast<ProjectionType*>(t);
Assert(proj != 0x0, "Error: dynamic cast failed!\n");
return allocation_helper(pt, v, count_pointers(pt));
}
case 5: {
VoidType *vt = dynamic_cast<VoidType*>(t);
Assert(vt != 0x0, "Error: dynamic cast failed!\n");
return allocation_helper(vt, v, count_pointers(pt));
}
default: {
Assert(1 == 0, "Error: unknown type!\n");
}
}
}
CCSTStatement* AllocateTypeVisitor::visit(ProjectionType *pt, Variable *v)
{
std::vector<CCSTAssignExpr*> malloc_args;
TypeNameVisitor *worker = new TypeNameVisitor();
malloc_args.push_back(new CCSTUnaryExprSizeOf(pt->accept(worker) ));
new CCSTPostFixExprAssnExpr( new CCSTPrimaryExprId("malloc")
, malloc_args);
std::vector<ProjectionField*> fields = pt->fields();
for(std::vector<ProjectionField*>::iterator it = fields.begin(); it != fields.end(); it ++) {
ProjectionField *pf = (ProjectionField*) *it;
Type *t = pf->type();
if(pointer_to_struct(t)) {
this->visit(pf); // change to visit variables ?
}
}
}
CCSTStatement* AllocateTypeVisitor::allocation_helper(ProjectionType *proj, Variable *v, int pointer_count)
{
std::vector<CCSTDeclaration*> declarations;
std::vector<CCSTStatement*> statements;
if(pointer_count == 0) { // case 1, not a pointer to a struct
std::vector<CCSTAssignExpr*> malloc_args;
TypeNameVisitor *worker = new TypeNameVisitor();
malloc_args.push_back(new CCSTUnaryExprSizeOf(proj->accept(worker)));
if(v->accessor() != 0x0) { // subcase, variable does not need to be declared.
statements.push_back(new CCSTAssignExpr(access_variable(v)
, new CCSTAssignOP(equal_t)
, new CCSTUnaryExprCastExpr(new CCSTUnaryOp(unary_mult_t)
,new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,malloc_args))));
} else { // variable needs to be declared
std::vector<CCSTDecSpecifier*>specifier;
specifier.push_back( new CCSTStructUnionSpecifier(struct_t, proj->real_type()));
std::vector<CCSTInitDeclarator*> decs;
decs.push_back(new CCSTInitDeclarator(new CCSTDeclarator(0x0, new CCSTDirectDecId(v->identifier()))
,new CCSTInitializer(new CCSTUnaryExprCastExpr( new CCSTUnaryOp(unary_mult_t)
,new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,malloc_args)))));
declarations.push_back(new CCSTDeclaration(specifier, decs));
}
} else if(pointer_count == 1) { // pointer to projection
std::vector<CCSTAssignExpr*> malloc_args;
TypeNameVisitor *worker = new TypeNameVisitor();
malloc_args.push_back(new CCSTUnaryExprSizeOf(proj->accept(worker)));
if(v->accessor() != 0x0) { // variable DOES NOT need to be declared
statements.push_back(new CCSTAssignExpr(access_variable(v)
, new CCSTAssignOP(equal_t)
,new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,malloc_args)));
} else { // variable DOES need to be declared
std::vector<CCSTDecSpecifier*>specifier;
specifier.push_back( new CCSTStructUnionSpecifier(struct_t, proj->real_type()));
std::vector<CCSTInitDeclarator*> decs;
decs.push_back(new CCSTInitDeclarator(new CCSTDeclarator(new CCSTPointer()
, new CCSTDirectDecId(v->identifier()))
,new CCSTInitializer(new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,malloc_args))));
declarations.push_back(new CCSTDeclaration(specifier, decs));
}
} else { // pointer count is greater than 1.
// need a temp variable.
SymbolTable *st = v->scope()->symbol_table();
const char* tmp_id = st->unique_tmp();
std::vector<CCSTAssignExpr*> struct_malloc_args;
TypeNameVisitor *worker = new TypeNameVisitor();
struct_malloc_args.push_back(new CCSTUnaryExprSizeOf(pt->accept(worker) ));
std::vector<CCSTDecSpecifier*>specifier;
specifier.push_back( new CCSTStructUnionSpecifier(struct_t, proj->real_type()));
std::vector<CCSTInitDeclarator*> decs;
decs.push_back(new CCSTInitDeclarator(new CCSTDeclarator(new CCSTPointer()
, new CCSTDirectDecId(tmp_id))
,new CCSTInitializer(new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,struct_malloc_args))));
declarations.push_back(new CCSTDeclaration(specifier, decs));
for(int i = 0; i < pointer_count-2; i ++) {
Assert(1 == 0, "Error: 3 pointers not supported at the moment.\n");
}
std::vector<CCSTAssignExpr*> pointer_malloc_args;
pointer_malloc_args.push_back(new CCSTUnaryExprSizeOf(worker->helper(proj, new CCSTPointer())));
if(v->accessor() != 0x0) { // variable DOES NOT need to be declared
} else { // variable NEEDS to be declared
std::vector<CCSTDecSpecifier*> var_spec;
specifier.push_back( new CCSTStructUnionSpecifier(struct_t, proj->real_type()));
std::vector<CCSTInitDeclarator*> var_decs;
decs.push_back(new CCSTInitDeclarator(new CCSTDeclarator(new CCSTPointer( new CCSTPointer())
, new CCSTDirectDecId(v->identifier()))
,new CCSTInitializer(new CCSTPostFixExprAssnExpr(new CCSTPrimaryExprId("malloc")
,pointer_malloc_args))));
declarations.push_back(new CCSTDeclaration(var_spec, var_decs));
}
statements.push_back(new CCSTAssignExpr(new CCSTUnaryExprCastExpr(new CCSTUnaryOp(unary_mult_t)
, access_variable(v))
, new CCSTAssignOP(equal_t)
, new CCSTPrimaryExprId(tmp_id)));
}
// have allocated space for struct. need to allocate space for fields if necessary
std::vector<ProjectionField*> fields = proj->fields();
for(std::vector<ProjectionField*>::iterator it = fields.begin(); it != fields.end(); it ++) {
ProjectionField *pf = (ProjectionField*) *it;
if(pointer_to_struct(pf->type())) {
statements.push_back(pf->accept(this)):
}
}
return new CCSTCompoundStatement(declarations, statements);
}
CCSTStatement* AllocateTypeVisitor::allocation_helper(Typedef *td, Variable *v, int pointer_count)
{
Assert(1 == 0, "Not implemented.\n");
}
CCSTStatement* AllocateTypeVisitor::allocation_helper(VoidType *vt, Variable *v, int pointer_count)
{
Assert(1 == 0, "Not implemented.\n");
}
CCSTStatement* AllocateTypeVisitor::allocation_helper(IntegerType *it, Variable *v, int pointer_count)
{
Assert(1 == 0, "Not implemented.\n");
}
bool AllocateTypeVisitor::pointer_to_struct(Type *t)
{
while(t->num() == 3) {
PointerType *pt = dynamic_cast<PointerType*>(t);
t = pt->type();
if(t->num() == 4) {
return true;
}
}
return false;
}
int AllocateTypeVisitor::count_pointers(PointerType *pt)
{
if(pt->type()->num != 3)
return 1;
PointerType *p = dynamic_cast<PointerType*>(pt->type());
Assert(p != 0x0, "Error: dynamic cast failed!\n");
return count_pointers(p) + 1;
}
Type* AllocateTypeVisitor::first_non_pointer(PointerType *pt)
{
if(pt->type()->num != 3)
return pt->type();
PointerType *p = dynamic_cast<PointerType*>(pt->type());
Assert(p != 0x0, "Error: dynamic cast failed!\n");
return first_non_pointer(p);
}
......@@ -12,6 +12,7 @@
class MarshalVisitor;
enum PrimType {pt_char_t, pt_short_t, pt_int_t, pt_long_t, pt_longlong_t, pt_capability_t};
enum type_k {};
template<class T, class T2>
class ASTVisitor;
......@@ -26,8 +27,21 @@ class Type : public Base
{
public:
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data) = 0;
virtual CCSTTypeName* accept(TypeNameVisitor *worker) = 0;
virtual int num() = 0;
// virtual ~Type(){printf("type destructor\n");}
};
class Variable : public Base
{
public:
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data) = 0;
virtual Type* type() = 0;
virtual const char* identifier() = 0;
virtual void set_accessor(Variable *v) = 0;
virtual Variable* accessor() = 0;
virtual Marshal_type* marshal_info() = 0;
virtual Rpc* scope() = 0;
};
class Scope : public Base
......@@ -73,9 +87,10 @@ class Typedef : public Type
public:
Typedef(const char* alias, Type* type);
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
Type* type() { return this->type_; }
virtual CCSTTypeName* accept(TypeNameVisitor *worker);
Type* type();
const char* alias();
virtual int num() {return 1;}
virtual int num();
// virtual void marshal();
};
......@@ -84,7 +99,8 @@ class VoidType : public Type
public:
VoidType();
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
virtual int num() {return 5;}
virtual CCSTTypeName* accept(TypeNameVisitor *worker);
virtual int num();
};
class IntegerType : public Type
......@@ -96,47 +112,44 @@ class IntegerType : public Type
public:
IntegerType(PrimType type, bool un, int size);
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
virtual CCSTTypeName* accept(TypeNameVisitor *worker);
PrimType int_type();
bool is_unsigned();
virtual int num() {return 2;}
virtual int num();
~IntegerType(){printf("inttype destructor\n");}
};
/*
class CapabilityType : public IntegerType
{
// is this needed?
};
*/
class PointerType : public Type
{
Type* type_;
public:
PointerType(Type* type);
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
Type* type() { return this->type_; }
virtual int num() {return 3;}
virtual CCSTTypeName* accept(TypeNameVisitor *worker);
Type* type();
virtual int num();
~PointerType(){printf("pointer type destructor\n");}
};
class ProjectionField : public Base
class ProjectionField : public Variable //?
{
bool in_;
bool out_;
bool alloc_;
bool bind_;
Type* field_type_;
const char* field_name_;
Variable *accessor_; //
public:
ProjectionField(bool in, bool out, bool alloc, bool bind, Type* field_type, const char* field_name);
ProjectionField(bool in, bool out, bool alloc, bool bind, Type* field_type, const char* field_name, ProjectionType *container_projection);
~ProjectionField();
Type* type() { return this->field_type_; }
const char* field_name() { return this->field_name_; }
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
virtual Type* type();
virtual Rpc* scope();
virtual const char* identifier();
virtual void set_accessor(Variable *v);
virtual Variable* accessor();
bool in();
bool out();
bool alloc();
bool bind();
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
};
class ProjectionType : public Type // complex type
......@@ -148,88 +161,106 @@ class ProjectionType : public Type // complex type
public:
ProjectionType(const char* id, const char* real_type, std::vector<ProjectionField*> fields);
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
virtual CCSTTypeName* accept(TypeNameVisitor *worker);
const char* id();
const char* real_type();
std::vector<ProjectionField*> fields() { return this->fields_; }
virtual int num() { printf("calling projectiontype num\n"); return 4;}
std::vector<ProjectionField*> fields();
virtual int num();
~ProjectionType(){printf("projection type destructor\n");}
};
class Parameter : public Base
class Parameter : public Variable
{
Type* type_;
const char* name_;
Marshal_type *marshal_info_;
bool in_;
bool out_;
bool alloc_;
bool bind_;
Variable *accessor_;
Rpc *function_;
public:
Parameter(Type* type, const char* name);
~Parameter();
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
Type* type() { return this->type_; }
void set_marshal_info(Marshal_type* mt) { this->marshal_info_ = mt; }
Marshal_type* get_marshal_info() { return this->marshal_info_; }
const char* name();
virtual Type* type();
virtual Rpc* scope();
void set_marshal_info(Marshal_type* mt); // ??????????????????????????????
Marshal_type* marshal_info(); //???????????????????????????????????
virtual const char* identifier();
virtual void set_accessor(Variable *v);
virtual bool bind();
virtual bool alloc();
virtual bool in();
virtual bool out();
virtual Variable* accessor();
};
class Rpc : public Base
class ReturnVariable : public Variable
{
const char* enum_name_;
/* special case */
Type* explicit_ret_type_;
std::vector<Type*> implicit_ret_types_; // can "Return" struct fields
Marshal_type *explicit_ret_marshal_info_;
std::vector<Marshal_type*> implicit_ret_marshal_info_;
/* -------------- */
char* name_;
std::vector<Parameter* > params_;
const char* name_; // to be decided by a name space or something
Type* type_;
Marshal_type *marshal_info_;
Variable* accessor_;
Rpc* function_;
public:
Rpc(Type* return_type, char* name, std::vector<Parameter* > parameters);
char* name();
Type* explicit_return_type() { return this->explicit_ret_type_; }
std::vector<Type*> implicit_return_types() { return this->implicit_ret_types_; }
std::vector<Parameter*> parameters();
std::vector<Marshal_type*> implicit_ret_marshal_info() { return this->implicit_ret_marshal_info_; }
void set_implicit_ret_marshal_info(std::vector<Marshal_type*> mt) { this->implicit_ret_marshal_info_ = mt; }
Marshal_type* explicit_ret_marshal_info() { return this->explicit_ret_marshal_info_; }
void set_explicit_ret_marshal_info(Marshal_type *mt) { this->explicit_ret_marshal_info_ = mt; }
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
ReturnValue();
ReturnValue(Type* return_type);
void set_marshal_info(Marshal_type *mt);
Marshal_type* marshal_info();
const char* enum_name();
const char* callee_name();
virtual const char* identifier();
virtual Type* type();
virtual void set_accessor(Variable *v);
virtual Rpc* scope();
virtual Variable* accessor();
};
/*
class MessageField
class ImplicitReturnVariable : public ReturnVariable
{
Type* field_type_;
char* field_name_;
Parameter* p_;
Marshal_type *marshal_info_;
Variable *accessor_;
Rpc* function_;
public:
MessageField(Type* field_type, char* field_name) {
this->field_type_ = field_type;
this->field_name_ = field_name; }
void accept(ASTVisitor *worker) { worker->visit(this); }
ImplicitReturnValue(Parameter *p);
void set_marshal_info(Marshal_type *mt);
Marshal_type* marshal_info();
virtual void set_accessor(Variable *v);
virtual Type* type();
virtual const char* identifier();
virtual Rpc* scope();
virtual Variable* accessor();
};
class Message : public Definition
class Rpc : public Base
{
char * name_;
std::vector<MessageField* >* fields_;
const char* enum_name_;
SymbolTable *symbol_table_;
ReturnValue *explicit_return_;
std::vector<ImplicitReturnValue*> implicit_returns_;
/* -------------- */
char* name_;
std::vector<Parameter* > parameters_;
std::vector<Parameter* > marshal_parameters_;
void set_implicit_returns();
public:
Message(char * name, std::vector<MessageField* >* fields) {
this->name_ = name;
this->fields_ = fields; }
DefinitionType get_definition_type() { return kMessage; }
void accept(ASTVisitor *worker) { worker->visit(this); }
Rpc(ReturnValue *return_value, char* name, std::vector<Parameter* > parameters);
char* name();
const char* enum_name();
const char* callee_name();
std::vector<Parameter*> parameters();
virtual Marshal_type* accept(MarshalVisitor *worker, Registers *data);
ReturnValue *return_value();
SymbolTable* symbol_table();
};
*/
class File : public Base
{
......@@ -245,22 +276,44 @@ class File : public Base
};
/*
template<class T, class T2>
class ASTVisitor
class TypeNameVisitor // generates CCSTTypeName for each type.
{
public:
virtual T* visit(File *file, T2 *data) = 0;
// virtual T visit(Message *message) = 0;
// virtual T visit(MessageField *message_field) = 0;
virtual T* visit(ProjectionField *proj_field, T2 *data) = 0;
virtual T* visit(Rpc *rpc, T2 *data) = 0;
virtual T* visit(Parameter *parameter, T2 *data) = 0;
virtual T* visit(Typedef *type_def, T2 *data) = 0;
virtual T* visit(ProjectionType *proj_type, T2 *data) = 0;
virtual T* visit(PointerType *pointer_type, T2 *data) = 0;
virtual T* visit(IntegerType *integer_type, T2 *data) = 0;
virtual T* visit(VoidType *vt, T2 *data) = 0;
CCSTTypeName* visit(Typedef *td);
CCSTTypeName* visit(VoidType *vt);
CCSTTypeName* visit(IntegerType *it);
CCSTTypeName* visit(PointerType *pt);
CCSTTypeName* visit(ProjectionType *pt);
};
*/
class AllocateTypeVisitor
{
Type* first_non_pointer(PointerType *pt);
int count_pointers(PointerType *pt);
bool pointer_to_struct(Type *t);
CCSTStatement* allocation_helper(IntegerType *it, Variable *v, int pointer_count);
CCSTStatement* allocation_helper(VoidType *vt, Variable *v, int pointer_count);
CCSTStatement* allocation_helper(Typedef *vt, Variable *v, int pointer_count);
CCSTStatement* allocation_helper(ProjectionType *vt, Variable *v, int pointer_count);
public:
AllocateTypeVisitor();
CCSTStatement* visit(Typedef *td);
CCSTStatement* visit(VoidType *vt);
CCSTStatement* visit(IntegerType *it);
CCSTStatement* visit(PointerType *pt);
CCSTStatement* visit(ProjectionType *pt);
};
class AllocateVariableVisitor
{
public:
AllocateVariableVisitor();
CCSTStatement* visit(ProjectionField *pf);
CCSTStatement* visit(Parameter *p);
CCSTStatement* visit(ReturnVariable *rv);
CCSTStatement* visit(ImplicitReturnVariable *irv);
};
#endif
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