Adding support for functions.

This commit is contained in:
Stefano Sanfilippo 2014-11-30 13:03:45 +01:00
parent ad80fc5130
commit 76a4e3d7f2
5 changed files with 60 additions and 21 deletions

View File

@ -79,6 +79,7 @@ static std::stack<StatementList*> stmtStack;
static std::stack<ExpressionList*> argsStack; static std::stack<ExpressionList*> argsStack;
static std::stack<IdList*> paramsStack; static std::stack<IdList*> paramsStack;
static std::stack<BranchCaseList*> branchCaseStack; static std::stack<BranchCaseList*> branchCaseStack;
static std::stack<FunArgList*> funArgStack;
} }
%union { %union {
@ -105,18 +106,20 @@ static std::stack<BranchCaseList*> branchCaseStack;
Id* idval; Id* idval;
Number* numericval; Number* numericval;
Function* funval; Function* funval;
FunArg *argval;
Main* mainval; Main* mainval;
} }
%type<intval> NUMBER %type<intval> NUMBER
%type<floatval> FLOAT %type<floatval> FLOAT
%type<strval> ID %type<strval> ID
%type<typeval> TYPENAME %type<typeval> TYPENAME fun_return
%type<statementval> statement %type<statementval> statement
%type<statlistval> branch_body %type<statlistval> branch_body
%type<assertval> assert_stmt %type<assertval> assert_stmt
%type<callval> fun_call %type<callval> fun_call
%type<argval> arg_decl
%type<funval> fun_decl %type<funval> fun_decl
%type<printval> print_stmt %type<printval> print_stmt
%type<inputval> input_stmt %type<inputval> input_stmt
@ -152,28 +155,36 @@ fun_decls:
fun_decls fun_decls
; ;
fun_decl: fun_decl:
FUNDECL ID { FUNDECL fun_return ID {
paramsStack.push(new IdList()); funArgStack.push(new FunArgList());
} args FUN_END { } args FUN_END {
stmtStack.push(new StatementList()); stmtStack.push(new StatementList());
} }
statements { statements {
$$ = new Function(new Id($2), paramsStack.top(), stmtStack.top()); $$ = new Function(new Id($3), $2, funArgStack.top(), stmtStack.top());
paramsStack.pop(); funArgStack.pop();
stmtStack.pop(); stmtStack.pop();
} }
; ;
args: fun_return:
/* epsilon */ | PARAMS arglist /* epsilon */ { $$ = Type::VOID; } | TYPENAME { $$ = $1; }
; ;
arglist: args:
variable { /* epsilon */ | PARAMS args_decl
paramsStack.top()->push_back($1); ;
args_decl:
arg_decl {
funArgStack.top()->push_back($1);
} }
| variable { | arg_decl {
paramsStack.top()->push_back($1); funArgStack.top()->push_back($1);
}
COMMA args_decl
;
arg_decl:
variable pointer TYPENAME {
$$ = new FunArg($1, $3, $2);
} }
arglist
; ;
main: main:
MAIN { MAIN {

View File

@ -40,6 +40,9 @@ std::ostream& monicelli::operator<<(std::ostream &stream, const Type &type) {
case Type::DOUBLE: case Type::DOUBLE:
stream << "double"; stream << "double";
break; break;
case Type::VOID:
stream << "void";
break;
} }
return stream; return stream;
@ -185,10 +188,15 @@ void FunctionCall::emit(std::ostream &stream, int indent) {
stream << ")"; stream << ")";
} }
void FunArg::emit(std::ostream &stream, int indent) {
stream << type << (pointer? "* ": " ");
name->emit(stream);
}
void Function::emit(std::ostream &stream, int indent) { void Function::emit(std::ostream &stream, int indent) {
emitIndent(stream, indent); emitIndent(stream, indent);
stream << "void "; stream << type << ' ';
name->emit(stream); name->emit(stream);
stream << "("; stream << "(";
args->emit(stream); args->emit(stream);

View File

@ -31,7 +31,8 @@ enum class Type {
CHAR, CHAR,
FLOAT, FLOAT,
BOOL, BOOL,
DOUBLE DOUBLE,
VOID
}; };
std::ostream& operator<<(std::ostream &stream, const Type &type); std::ostream& operator<<(std::ostream &stream, const Type &type);
@ -285,20 +286,39 @@ private:
}; };
class FunArg: public Emittable {
public:
FunArg(Id *n, Type t, bool p): name(n), type(t), pointer(p) {}
virtual ~FunArg() {}
virtual void emit(std::ostream &stream, int indent = 0);
private:
Pointer<Id> name;
Type type;
bool pointer;
};
typedef ListEmittable<FunArg> FunArgList;
class Function: public Emittable { class Function: public Emittable {
public: public:
Function(Id *n, IdList *a, StatementList *b): Function(Id *n, Type r, FunArgList *a, StatementList *b):
name(n), args(a), body(b) {} name(n), type(r), args(a), body(b) {}
virtual ~Function() {} virtual ~Function() {}
virtual void emit(std::ostream &stream, int indent = 0); virtual void emit(std::ostream &stream, int indent = 0);
private: private:
Pointer<Id> name; Pointer<Id> name;
Pointer<IdList> args; Type type;
Pointer<FunArgList> args;
Pointer<StatementList> body; Pointer<StatementList> body;
}; };
class Program: public Emittable { class Program: public Emittable {
public: public:
virtual void emit(std::ostream &stream, int indent = 0); virtual void emit(std::ostream &stream, int indent = 0);

View File

@ -40,7 +40,7 @@ Lei ha clacsonato
vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco o scherziamo, vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco o scherziamo,
vaffanzum 0! vaffanzum 0!
blinda la supercazzola antanizzata con alfio o scherziamo? blinda la supercazzola Necchi antanizzata con alfio Mascetti, barilotto Necchi o scherziamo?
vaffanzum alfio meno 2! vaffanzum alfio meno 2!
bituma al finale? bituma al finale?

View File

@ -10,5 +10,5 @@ o tarapia tapioco: mi porga il cappello e velocità di esecuzione,
vicesindaco a posterdati, mi porga il vicesindaco, brematurata la supercazzola vicesindaco a posterdati, mi porga il vicesindaco, brematurata la supercazzola
tombale con alfio, serio o scherziamo? avvertite don ulrico, ho visto la signora! tombale con alfio, serio o scherziamo? avvertite don ulrico, ho visto la signora!
vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco
o scherziamo, vaffanzum 0! blinda la supercazzola antanizzata con alfio o scherziamo? o scherziamo, vaffanzum 0! blinda la supercazzola Necchi antanizzata con alfio
vaffanzum alfio meno 2! bituma al finale? Mascetti o scherziamo? vaffanzum alfio meno 2! bituma al finale?