Added arbitrary length functions.
This commit is contained in:
parent
907bc26264
commit
2ce89fb39a
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
32
src/lexer.c
32
src/lexer.c
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user