Added arbitrary length functions.

This commit is contained in:
Jacob Signorovitch 2025-01-11 10:35:42 -05:00
parent 907bc26264
commit 2ce89fb39a
5 changed files with 85 additions and 8 deletions

View File

@ -17,7 +17,7 @@ include the [Unity](https://github.com/ThrowTheSwitch/Unity) test framework.
- [x] Negative numbers
- [x] Basic binary infix operators; `+`, `-`, `*`, `/`
- [x] The same as conventional functions; `sum()`, `sub()`, `mul()`, `div()`
- [ ] Arbitrary length functions
- [x] Arbitrary length functions
- [ ] User-defined variables
- [ ] Control flow
- [ ] User-defined functions

View File

@ -41,6 +41,12 @@ ASTNumData exec_call(AST* ast) {
ASTNumData n2 = exec_expr(calldata->argv[1]);
return n1 / n2;
} else if (!strcmp(calldata->to, "sum") && calldata->argc == 3) {
ASTNumData n1 = exec_expr(calldata->argv[0]);
ASTNumData n2 = exec_expr(calldata->argv[1]);
ASTNumData n3 = exec_expr(calldata->argv[2]);
return n1 + n2 + n3;
}
return -1000;
}

View File

@ -17,6 +17,7 @@
double fval;
char* strval;
AST* ast;
ArgArr* argarr;
}
%define parse.error verbose
@ -41,6 +42,8 @@
%type<fval> num;
%type<ast> exp;
%type<argarr> arg;
%type<argarr> argstart;
%%
@ -54,15 +57,35 @@ num:
| SUB NUM { $$ = -$2; } %prec NEG
;
argstart:
exp {
ArgArr* argarr = argarr_init();
argarr_add(argarr, $1);
$$ = argarr;
}
arg:
argstart { $$ = $1; }
| arg SEP exp {
argarr_add($1, $3);
$$ = $1;
}
;
exp:
num { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
// name(thing, thing)
| CALL LGROUP exp SEP exp RGROUP {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $3;
argv[1] = $5;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, 2, argv));
// name(thing-1, thing-2, ..., thing-n)
// name(thing)
// name()
// larg: lgroup marg
// lgroup rgroup
// marg: exp sep marg
// exp rgroup
| CALL LGROUP arg RGROUP {
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, $3->ln, $3->buf));
}
| exp PLUS exp {

View File

@ -2,11 +2,27 @@
#define LEXER_H
#include <assert.h>
#include <stddef.h>
#include "ast.h"
#define ARLN 8
extern char* inp;
typedef struct {
size_t sz;
size_t ln;
AST** buf;
} ArgArr;
ArgArr* argarr_init();
void argarr_destroy(ArgArr* argarr);
void argarr_add(ArgArr* argarr, AST* arg);
#include "../../build/grammars/grammar.tab.h"
extern YYSTYPE yylval;
extern char* inp;
// Accumulate an integer.
int acc_int(int c);

View File

@ -1,11 +1,43 @@
#include <complex.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include "include/dstr.h"
#include "include/util.h"
#include "include/lexer.h"
ArgArr* argarr_init() {
ArgArr* argarr = malloc(sizeof(ArgArr));
argarr->sz = ARLN;
argarr->ln = 0;
argarr->buf = malloc(ARLN);
return argarr;
}
void argarr_destroy(ArgArr* argarr) {
free(argarr->buf);
free(argarr);
}
void argarr_add(ArgArr* argarr, AST* arg) {
if (argarr->ln + 1 > argarr->sz) {
argarr->sz *= 2;
argarr->buf = realloc(argarr->buf, argarr->sz);
log_dbgf(
"ArgArr @ %p doubled from %ld to %ld",
argarr,
argarr->sz/2,
argarr->sz
);
}
argarr->buf[argarr->ln++] = arg;
}
int acc_int(int c) {
int value = c - '0';
while (isdigit(*inp)) {