pic_get_args supports optional argument
This commit is contained in:
parent
6c8dd50ab8
commit
86177b7c4e
|
@ -62,7 +62,7 @@ void pic_gc_arena_restore(pic_state *, int);
|
||||||
pic_state *pic_open(int argc, char *argv[], char **envp);
|
pic_state *pic_open(int argc, char *argv[], char **envp);
|
||||||
void pic_close(pic_state *);
|
void pic_close(pic_state *);
|
||||||
|
|
||||||
void pic_get_args(pic_state *, const char *, ...);
|
int pic_get_args(pic_state *, const char *, ...);
|
||||||
void pic_defun(pic_state *, const char *, pic_func_t);
|
void pic_defun(pic_state *, const char *, pic_func_t);
|
||||||
|
|
||||||
bool pic_eq_p(pic_state *, pic_value, pic_value);
|
bool pic_eq_p(pic_state *, pic_value, pic_value);
|
||||||
|
|
|
@ -110,4 +110,3 @@ pic_init_port(pic_state *pic)
|
||||||
pic_defun(pic, "write", pic_port_write);
|
pic_defun(pic, "write", pic_port_write);
|
||||||
pic_defun(pic, "newline", pic_port_newline);
|
pic_defun(pic, "newline", pic_port_newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
src/vm.c
33
src/vm.c
|
@ -7,22 +7,38 @@
|
||||||
#include "picrin/irep.h"
|
#include "picrin/irep.h"
|
||||||
#include "picrin/string.h"
|
#include "picrin/string.h"
|
||||||
|
|
||||||
void
|
#define GET_OPERAND(pic,n) ((pic)->sp[-1-(n)])
|
||||||
|
|
||||||
|
int
|
||||||
pic_get_args(pic_state *pic, const char *format, ...)
|
pic_get_args(pic_state *pic, const char *format, ...)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
int i = -1;
|
int i = 0, argc = pic->ci->argc - 1;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
bool opt = false;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
while ((c = *format++)) {
|
while ((c = *format++)) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
default:
|
||||||
|
if (argc <= i && ! opt) {
|
||||||
|
pic_error(pic, "wrong number of arguments");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case '|':
|
||||||
|
opt = true;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
{
|
{
|
||||||
pic_value *p;
|
pic_value *p;
|
||||||
|
|
||||||
p = va_arg(ap, pic_value*);
|
p = va_arg(ap, pic_value*);
|
||||||
*p = pic->sp[i--];
|
*p = GET_OPERAND(pic,i);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -30,7 +46,8 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
||||||
double *f;
|
double *f;
|
||||||
|
|
||||||
f = va_arg(ap, double *);
|
f = va_arg(ap, double *);
|
||||||
*f = pic_float(pic->sp[i--]);
|
*f = pic_float(GET_OPERAND(pic,i));
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
|
@ -41,13 +58,19 @@ pic_get_args(pic_state *pic, const char *format, ...)
|
||||||
|
|
||||||
cstr = va_arg(ap, char **);
|
cstr = va_arg(ap, char **);
|
||||||
len = va_arg(ap, size_t *);
|
len = va_arg(ap, size_t *);
|
||||||
str = pic->sp[i--];
|
str = GET_OPERAND(pic,i);
|
||||||
*cstr = pic_str_ptr(str)->str;
|
*cstr = pic_str_ptr(str)->str;
|
||||||
*len = pic_str_ptr(str)->len;
|
*len = pic_str_ptr(str)->len;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (argc > i) {
|
||||||
|
pic_error(pic, "wrong number of arguments");
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PIC_DIRECT_THREADED_VM
|
#if PIC_DIRECT_THREADED_VM
|
||||||
|
|
Loading…
Reference in New Issue