[hackers] [sbase] bc: Unwind the stack in every return || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Fri, 28 Nov 2025 12:36:23 +0100 (CET)

commit 98923f69a1bb852d7fcbf2146dec4a084874bf80
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.net>
AuthorDate: Fri Nov 28 12:34:55 2025 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.net>
CommitDate: Fri Nov 28 12:34:55 2025 +0100

    bc: Unwind the stack in every return
    
    When we return from a function we have to unwind the stack and
    pop all the locals of that function. That requires to create
    a string with all the pop information to be used in every return.

diff --git a/bc.y b/bc.y
index e3e0f4d..51f4649 100644
--- a/bc.y
+++ b/bc.y
_AT_@ -49,7 +49,7 @@ static char *var(char *);
 static char *ary(char *);
 static void writeout(char *);
 
-static char *yytext, *buff;
+static char *yytext, *buff, *unwind;
 static char *filename;
 static FILE *filep;
 static int lineno, nerr, flowid;
_AT_@ -158,29 +158,29 @@ for : FOR {$$ = macro(LOOP);}
 def : DEF ID {$$ = macro(DEF);}
         ;
 
-parlst : '(' ')' {$$ = code("%%s");}
+parlst : '(' ')' {$$ = code("");}
         | '(' params ')' {$$ = $2;}
         ;
 
-params : param
- | params ',' param {$$ = code($1, $3); free($1);}
+params : param {$$ = param(NULL, $1);}
+ | params ',' param {$$ = param($1, $3);}
         ;
 
-param : ID {$$ = code("S%s%%sL%ss.", var($1), var($1));}
- | ID '[' ']' {$$ = code("S%s%%sL%ss.", ary($1), ary($1));}
+param : ID {$$ = var($1);}
+ | ID '[' ']' {$$ = ary($1);}
         ;
 
-autolst : {$$ = code("%%s");}
+autolst : {$$ = code("");}
         | AUTO locals '\n' {$$ = $2;}
         | AUTO locals ';' {$$ = $2;}
         ;
 
-locals : local
- | locals ',' local {$$ = code($1, $3); free($1);}
+locals : local {$$ = local(NULL, $1);}
+ | locals ',' local {$$ = local($1, $3);}
         ;
 
-local : ID {$$ = code("0S%s%%sL%ss.", var($1), var($1));}
- | ID '[' ']' {$$ = code("0S%s%%sL%ss.", ary($1), ary($1));}
+local : ID {$$ = var($1);}
+ | ID '[' ']' {$$ = ary($1);}
         ;
 
 arglst : expr
_AT_@ -379,19 +379,50 @@ macro(int op)
 }
 
 static char *
-funcode(Macro *d, char *params, char *vars, char *body)
+param(char *list, char *id)
+{
+ char *i1, *i2;
+
+ i1 = estrdup(id);
+ i2 = estrdup(id);
+ free(id);
+
+ unwind = code(unwind ? "L%ss.%s" : "L%ss.", i1, unwind);
+
+ return code(list ? "S%s%s" : "S%s" , i2, list);
+}
+
+static char *
+local(char *list, char *id)
 {
- char *s, *t1, *t2;
+ char *i1, *i2;
 
- t1 = code(vars, params);
- t2 = code(t1, body);
+ i1 = estrdup(id);
+ i2 = estrdup(id);
+ free(id);
 
+ unwind = code(unwind ? "L%ss.%s" : "L%ss.", i1, unwind);
+
+ return code(list ? "0S%s%s" : "0S%s" , i2, list);
+}
+
+static char *
+funcode(Macro *d, char *params, char *vars, char *body)
+{
+ char *s;
+
+ s = code("[%s%s%s%s]s%c",
+ vars, params,
+ body,
+ retcode(code(" 0")),
+ d->id);
+ free(unwind);
+ unwind = NULL;
         nested--;
         inhome = 0;
- free(vars);
- free(t1);
 
- return code("[%s 0 1Q]s%c", t2, d->id);
+
+ return s;
 }
 
 static char *
_AT_@ -415,7 +446,7 @@ forcode(Macro *d, char *init, char *cmp, char *inc, char *body)
                  body,
                  inc,
                  estrdup(cmp),
- d->flowid, d->id);
+ d->id, d->id);
         writeout(s);
 
         s = code("%ss.%s%c", init, cmp, d->id);
_AT_@ -432,7 +463,7 @@ whilecode(Macro *d, char *cmp, char *body)
         s = code("[%ss.%s%c]s%c",
                  body,
                  estrdup(cmp),
- d->flowid, d->id);
+ d->id, d->id);
         writeout(s);
 
         s = code("%s%c", cmp, d->id);
_AT_@ -462,7 +493,7 @@ retcode(char *expr)
 
         if (nested < 2 || macros[1].op != DEF)
                 yyerror("return must be in a function");
- return code("%s %dQ", expr, nested - 1);
+ return code("%s %s %dQ", estrdup(unwind), expr, nested - 1);
 }
 
 static char *
Received on Fri Nov 28 2025 - 12:36:23 CET

This archive was generated by hypermail 2.3.0 : Fri Nov 28 2025 - 12:48:37 CET