From 76a4e3d7f29b85ded864d758a9b496411e39d0f5 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Sun, 30 Nov 2014 13:03:45 +0100 Subject: [PATCH] Adding support for functions. --- Monicelli.ypp | 37 ++++++++++++++++++++++++------------- Nodes.cpp | 10 +++++++++- Nodes.hpp | 28 ++++++++++++++++++++++++---- examples/syntax.beauty.mc | 2 +- examples/syntax.mc | 4 ++-- 5 files changed, 60 insertions(+), 21 deletions(-) diff --git a/Monicelli.ypp b/Monicelli.ypp index d8e6bf3..7756ef5 100644 --- a/Monicelli.ypp +++ b/Monicelli.ypp @@ -79,6 +79,7 @@ static std::stack stmtStack; static std::stack argsStack; static std::stack paramsStack; static std::stack branchCaseStack; +static std::stack funArgStack; } %union { @@ -105,18 +106,20 @@ static std::stack branchCaseStack; Id* idval; Number* numericval; Function* funval; + FunArg *argval; Main* mainval; } %type NUMBER %type FLOAT %type ID -%type TYPENAME +%type TYPENAME fun_return %type statement %type branch_body %type assert_stmt %type fun_call +%type arg_decl %type fun_decl %type print_stmt %type input_stmt @@ -152,28 +155,36 @@ fun_decls: fun_decls ; fun_decl: - FUNDECL ID { - paramsStack.push(new IdList()); + FUNDECL fun_return ID { + funArgStack.push(new FunArgList()); } args FUN_END { stmtStack.push(new StatementList()); } statements { - $$ = new Function(new Id($2), paramsStack.top(), stmtStack.top()); - paramsStack.pop(); + $$ = new Function(new Id($3), $2, funArgStack.top(), stmtStack.top()); + funArgStack.pop(); stmtStack.pop(); } ; -args: - /* epsilon */ | PARAMS arglist +fun_return: + /* epsilon */ { $$ = Type::VOID; } | TYPENAME { $$ = $1; } ; -arglist: - variable { - paramsStack.top()->push_back($1); +args: + /* epsilon */ | PARAMS args_decl +; +args_decl: + arg_decl { + funArgStack.top()->push_back($1); } - | variable { - paramsStack.top()->push_back($1); + | arg_decl { + funArgStack.top()->push_back($1); + } + COMMA args_decl +; +arg_decl: + variable pointer TYPENAME { + $$ = new FunArg($1, $3, $2); } - arglist ; main: MAIN { diff --git a/Nodes.cpp b/Nodes.cpp index 92853f6..1ed587b 100644 --- a/Nodes.cpp +++ b/Nodes.cpp @@ -40,6 +40,9 @@ std::ostream& monicelli::operator<<(std::ostream &stream, const Type &type) { case Type::DOUBLE: stream << "double"; break; + case Type::VOID: + stream << "void"; + break; } return stream; @@ -185,10 +188,15 @@ void FunctionCall::emit(std::ostream &stream, int indent) { stream << ")"; } +void FunArg::emit(std::ostream &stream, int indent) { + stream << type << (pointer? "* ": " "); + name->emit(stream); +} + void Function::emit(std::ostream &stream, int indent) { emitIndent(stream, indent); - stream << "void "; + stream << type << ' '; name->emit(stream); stream << "("; args->emit(stream); diff --git a/Nodes.hpp b/Nodes.hpp index e635bb3..b51aeaa 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -31,7 +31,8 @@ enum class Type { CHAR, FLOAT, BOOL, - DOUBLE + DOUBLE, + VOID }; 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 name; + Type type; + bool pointer; +}; + + +typedef ListEmittable FunArgList; + + class Function: public Emittable { public: - Function(Id *n, IdList *a, StatementList *b): - name(n), args(a), body(b) {} + Function(Id *n, Type r, FunArgList *a, StatementList *b): + name(n), type(r), args(a), body(b) {} virtual ~Function() {} virtual void emit(std::ostream &stream, int indent = 0); private: Pointer name; - Pointer args; + Type type; + Pointer args; Pointer body; }; + class Program: public Emittable { public: virtual void emit(std::ostream &stream, int indent = 0); diff --git a/examples/syntax.beauty.mc b/examples/syntax.beauty.mc index 59f123a..4d180bc 100644 --- a/examples/syntax.beauty.mc +++ b/examples/syntax.beauty.mc @@ -40,7 +40,7 @@ Lei ha clacsonato vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco o scherziamo, 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! bituma al finale? diff --git a/examples/syntax.mc b/examples/syntax.mc index 2c21ac9..911d84a 100644 --- a/examples/syntax.mc +++ b/examples/syntax.mc @@ -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 tombale con alfio, serio o scherziamo? avvertite don ulrico, ho visto la signora! vicesindaco come se fosse brematurata la supercazzola avanti con il vicesindaco -o scherziamo, vaffanzum 0! blinda la supercazzola antanizzata con alfio o scherziamo? -vaffanzum alfio meno 2! bituma al finale? +o scherziamo, vaffanzum 0! blinda la supercazzola Necchi antanizzata con alfio +Mascetti o scherziamo? vaffanzum alfio meno 2! bituma al finale?