History

sl_process_args: helper to deal with keyworded args

Sigrid Solveig Haflínudóttir committed 3 months ago

Commit 35eb3131 parent cf62f775 files · +57 −31Browse files

Unified · Split

5 files
  1. src/io.c +13 −24
  2. src/sl.c +33 −0
  3. src/sl.h +3 −0
  4. src/slpriv.h +1 −0
  5. src/str.c +7 −7
src/io.c+13−24
@@ -7,7 +7,7 @@ · 6 unmodified lines
77
88 static sl_v iosym, rdsym, wrsym, apsym, crsym, truncsym;
99 static sl_v linesym, blocksym, memorysym;
10−static sl_v ioinsym, wssym, endsym, bendian, lendian;
10+static sl_v ioinsym, wssym, endsym, bendiansym, lendiansym;
1111 sl_v sl_iooutsym;
1212 const sl_type *sl_iotype;
1313
@@ -68,9 +68,9 @@ static bool · 54 unmodified lines
6868 isflipped(sl_v v)
6969 {
7070 bool little;
71− if(v == lendian)
71+ if(v == lendiansym)
7272 little = true;
73− else if(v == bendian)
73+ else if(v == bendiansym)
7474 little = false;
7575 else
7676 cthrow(error(sl_errarg, "invalid endian specifier"), v);
@@ -194,19 +194,12 @@ BUILTIN("buffer", buffer) · 117 unmodified lines
194194
195195 BUILTIN("read", read)
196196 {
197− bool ws = false;
198− if(sl_unlikely(nargs >= 2 && nargs <= 3)){
199− int i;
200− if(args[i = 0] == wssym || (nargs > 2 && args[i = 1] == wssym)){
201− ws = args[++i] != sl_nil;
202− if(i < 2) // (read :whitespace T io)
203− args[0] = args[2];
204− nargs -= 2;
205− }
206− }
207− sl_v a = nargs == 0 ? sym_value(ioinsym) : args[0];
197+ sl_v keys[] = {wssym}, values[1];
198+ nargs = sl_process_args(args, 0, nargs, keys, nelem(keys), values);
208199 if(sl_unlikely(nargs > 1))
209− argcount(1);
200+ bthrow(error(sl_errarg, "extra arguments"));
201+ bool ws = nonnil(values[0]);
202+ sl_v a = nargs == 0 ? sym_value(ioinsym) : args[0];
210203 USED(toio(a, true, true, false));
211204 sl_gc_handle(&a);
212205 sl_v v = sl_read_sexpr(a, ws);
@@ -300,15 +293,11 @@ BUILTIN("io-peek", io_peek) · 87 unmodified lines
300293
301294 BUILTIN("io-skip", io_skip)
302295 {
296+ sl_v keys[] = {endsym}, values[1];
297+ nargs = sl_process_args(args, 2, nargs, keys, nelem(keys), values);
298+ bool end = nonnil(values[0]);
303299 if(nargs != 2 && nargs != 4)
304300 argcount(2);
305− bool end = false;
306− if(nargs == 4){
307− if(args[2] == endsym)
308− end = args[3] != sl_nil;
309− else
310− bthrow(error(sl_errarg, "invalid arguments"));
311− }
312301 ios *s = toio(args[0], true, false, false);
313302 soffset off = tooffset(args[1]);
314303 soffset res = ios_skip(s, off, end);
@@ -616,8 +605,8 @@ io_init(void) · 301 unmodified lines
616605 wssym = mk_csym(":whitespace");
617606 endsym = mk_csym(":end");
618607 ioinsym = mk_csym("*io-in*");
619− bendian = mk_csym(":big-endian");
620− lendian = mk_csym(":little-endian");
608+ bendiansym = mk_csym(":big-endian");
609+ lendiansym = mk_csym(":little-endian");
621610 sl_iooutsym = mk_csym("*io-out*");
622611 sl_iotype = define_opaque_type(iosym, sizeof(ios), &io_vtable, nil);
623612 set(mk_csym("*stdout*"), cvalue_from_ref(sl_iotype, ios_stdout, sizeof(ios)));
src/sl.c+33−0
@@ -790,6 +790,39 @@ sl_do_trycatch(void) · 789 unmodified lines
790790 return v;
791791 }
792792
793+int
794+sl_process_args(sl_v *args, int nreq, int nargs, const sl_v *keys, int nkeys, sl_v *values)
795+{
796+ if(sl_unlikely(nargs < nreq))
797+ cthrow(arity_error(nargs, nreq), args);
798+ for(int k = 0; k < nkeys; k++)
799+ values[k] = sl_unbound;
800+ int nn = 0;
801+ for(int i = 0; i < nargs; i++){
802+ sl_v v = args[i];
803+ if(!issym(v) || !iskeyword(ptr(sl_sym, v))){
804+ args[nn++] = v;
805+ continue;
806+ }
807+ int k;
808+ for(k = 0; k < nkeys; k++){
809+ if(args[i] != keys[k])
810+ continue;
811+ if(values[k] != sl_unbound)
812+ cthrow(error(sl_errarg, "duplicate keyword %s ", sym_name(keys[k])), args);
813+ if(i+1 >= nargs)
814+ cthrow(error(sl_errarg, "keyword %s requires an argument", sym_name(keys[k])), args);
815+ values[k] = args[++i];
816+ break;
817+ }
818+ if(k == nkeys)
819+ args[nn++] = v;
820+ }
821+ if(sl_unlikely(nn < nreq))
822+ cthrow(error(sl_errarg, "required argument missing"), args);
823+ return nn;
824+}
825+
793826 /*
794827 argument layout on stack is
795828 |--required args--|--opt args--|--kw args--|--rest args...
src/sl.h+3−0
@@ -140,6 +140,9 @@ enum { · 139 unmodified lines
140140 #define vec_type(v) (vec_elt((v), -1) & VEC_TYPE_MASK)
141141 #define isstruct(v) (vec_type(v) == VEC_STRUCT)
142142
143+// supplied and non-NIL
144+#define nonnil(v) ((v) != sl_unbound && (v) != sl_nil)
145+
143146 // functions ending in _ are unsafe, faster versions
144147 #define car_(v) (ptr(sl_cons, (v))->car)
145148 #define cdr_(v) (ptr(sl_cons, (v))->cdr)
src/slpriv.h+1−0
@@ -227,6 +227,7 @@ _Noreturn void slmain(const u8int *boot, int bootsz, int argc, char **argv) sl_r · 226 unmodified lines
227227
228228 sl_v sl_list(sl_v *args, int nargs, bool star) sl_hotfn sl_nonnull(1);
229229 sl_v sl_do_trycatch(void);
230+int sl_process_args(sl_v *args, int nreq, int nargs, const sl_v *keys, int nkeys, sl_v *values);
230231 int sl_process_keys(sl_v kwtable, int nreq, int nkw, int nopt, usize bp, int nargs, int va);
231232 sl_v sl_vm_applyn(int n) sl_hotfn;
232233 sl_v sl_vm_apply_cl(int nargs) sl_hotfn;
src/str.c+7−7
@@ -719,16 +719,16 @@ get_radix_arg(sl_v arg) · 718 unmodified lines
719719
720720 BUILTIN("str->num", str_2_num)
721721 {
722− if(sl_unlikely(nargs != 1 && nargs != 3))
723− argcount(2);
722+ sl_v keys[] = {basesym}, values[1];
723+ nargs = sl_process_args(args, 1, nargs, keys, nelem(keys), values);
724+ if(nargs != 1)
725+ argcount(1);
724726 char *s = tostr(args[0]), *e;
725727 sl_v n;
726728 int base = 10;
727− if(nargs == 3 && sl_unlikely(args[1] != basesym))
728− bthrow(error(sl_errarg, "invalid argument at position %d", 1));
729− if(nargs == 3 && args[2] != sl_nil){
730− base = get_radix_arg(args[2]);
731− }else if(s[0] == '#'){
729+ if(nonnil(values[0]))
730+ base = get_radix_arg(values[0]);
731+ else if(s[0] == '#'){
732732 int c = tolower((u8int)s[1]);
733733 if(((c == 'b' && (base = 2)) ||
734734 (c == 'o' && (base = 8)) ||

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t