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] Negative numbers
|
||||||
- [x] Basic binary infix operators; `+`, `-`, `*`, `/`
|
- [x] Basic binary infix operators; `+`, `-`, `*`, `/`
|
||||||
- [x] The same as conventional functions; `sum()`, `sub()`, `mul()`, `div()`
|
- [x] The same as conventional functions; `sum()`, `sub()`, `mul()`, `div()`
|
||||||
- [ ] Arbitrary length functions
|
- [x] Arbitrary length functions
|
||||||
- [ ] User-defined variables
|
- [ ] User-defined variables
|
||||||
- [ ] Control flow
|
- [ ] Control flow
|
||||||
- [ ] User-defined functions
|
- [ ] User-defined functions
|
||||||
|
@ -41,6 +41,12 @@ ASTNumData exec_call(AST* ast) {
|
|||||||
ASTNumData n2 = exec_expr(calldata->argv[1]);
|
ASTNumData n2 = exec_expr(calldata->argv[1]);
|
||||||
|
|
||||||
return n1 / n2;
|
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;
|
return -1000;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
double fval;
|
double fval;
|
||||||
char* strval;
|
char* strval;
|
||||||
AST* ast;
|
AST* ast;
|
||||||
|
ArgArr* argarr;
|
||||||
}
|
}
|
||||||
|
|
||||||
%define parse.error verbose
|
%define parse.error verbose
|
||||||
@ -41,6 +42,8 @@
|
|||||||
|
|
||||||
%type<fval> num;
|
%type<fval> num;
|
||||||
%type<ast> exp;
|
%type<ast> exp;
|
||||||
|
%type<argarr> arg;
|
||||||
|
%type<argarr> argstart;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -54,15 +57,35 @@ num:
|
|||||||
| SUB NUM { $$ = -$2; } %prec NEG
|
| 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:
|
exp:
|
||||||
num { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
|
num { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
|
||||||
|
|
||||||
// name(thing, thing)
|
// name(thing-1, thing-2, ..., thing-n)
|
||||||
| CALL LGROUP exp SEP exp RGROUP {
|
// name(thing)
|
||||||
AST** argv = calloc(2, sizeof(AST*));
|
// name()
|
||||||
argv[0] = $3;
|
|
||||||
argv[1] = $5;
|
// larg: lgroup marg
|
||||||
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, 2, argv));
|
// 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 {
|
| exp PLUS exp {
|
||||||
|
@ -2,11 +2,27 @@
|
|||||||
#define LEXER_H
|
#define LEXER_H
|
||||||
|
|
||||||
#include <assert.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"
|
#include "../../build/grammars/grammar.tab.h"
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
extern YYSTYPE yylval;
|
||||||
extern char* inp;
|
|
||||||
|
|
||||||
// Accumulate an integer.
|
// Accumulate an integer.
|
||||||
int acc_int(int c);
|
int acc_int(int c);
|
||||||
|
32
src/lexer.c
32
src/lexer.c
@ -1,11 +1,43 @@
|
|||||||
|
#include <complex.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "include/dstr.h"
|
#include "include/dstr.h"
|
||||||
|
#include "include/util.h"
|
||||||
#include "include/lexer.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 acc_int(int c) {
|
||||||
int value = c - '0';
|
int value = c - '0';
|
||||||
while (isdigit(*inp)) {
|
while (isdigit(*inp)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user