scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 0d0b0348c1e5864db9ccb539f98e49299833f68b
parent 414ccc5a4e31eb805c5031d43f01d73c373019f7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 16 Apr 2014 12:54:23 +0200

Add return statement

Diffstat:
Mcc.h | 2+-
Mcode.c | 11+++++++++--
Mdecl.c | 7+++++--
Mexpr.c | 2+-
Mstmt.c | 28+++++++++++++++++++++++++---
5 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/cc.h b/cc.h @@ -233,7 +233,7 @@ enum { }; extern void - emitdcl(Symbol *), + emitdcl(Symbol *), emitsframe(Symbol *), emiteframe(Symbol *), emitsym(Node *), emitunary(Node *), emitbin(Node *), emitexp(Node *), emitconst(Node *np); diff --git a/code.c b/code.c @@ -171,17 +171,24 @@ emitfun(Symbol *sym) } void -emitframe(Symbol *sym) +emitsframe(Symbol *sym) { puts("{"); } void -emitret(Symbol *sym) +emiteframe(Symbol *sym) { puts("}"); } +void +emitret(Type *tp) +{ + fputs("\ty", stdout); + emittype(tp); +} + Node * castcode(Node *child, Type *tp) { diff --git a/decl.c b/decl.c @@ -497,9 +497,12 @@ extdecl(void) if (BTYPE(tp) == FTN) { emitfun(sym); if (yytoken == '{') { - emitframe(sym); + extern Symbol *curfun; + + curfun = sym; + emitsframe(sym); context(compound); - emitret(sym); + emiteframe(sym); /* FIX: sym is not used */ freesyms(NS_LABEL); return; } diff --git a/expr.c b/expr.c @@ -95,7 +95,7 @@ addr2ptr(Node *np) /* * Convert a Node to a type */ -static Node * +Node * convert(Node *np, Type *tp1, char iscast) { Type *tp2; diff --git a/stmt.c b/stmt.c @@ -4,18 +4,40 @@ #include "cc.h" +Symbol *curfun; + +extern void decl(void); +extern Node *expr(void); +extern Node *convert(Node *np, Type *tp1, char iscast); + +static void +Return(void) +{ + Node *np; + Type *tp = curfun->type->type; + + expect(RETURN); + np = expr(); + if (np->type != tp) { + if ((np = convert(np, tp, 0)) == NULL) + error("incorrect type in return"); + } + emitret(tp); + emitexp(np); +} + void compound(void) { - extern void decl(void); - extern Node *expr(void); - expect('{'); while (!accept('}')) { switch (yytoken) { case TYPE: case SCLASS: case TQUALIFIER: decl(); break; + case RETURN: + Return(); + break; default: emitexp(expr()); }