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
7 7
8static sl_v iosym, rdsym, wrsym, apsym, crsym, truncsym;8static sl_v iosym, rdsym, wrsym, apsym, crsym, truncsym;
9static sl_v linesym, blocksym, memorysym;9static sl_v linesym, blocksym, memorysym;
10static sl_v ioinsym, wssym, endsym, bendian, lendian;10static sl_v ioinsym, wssym, endsym, bendiansym, lendiansym;
11sl_v sl_iooutsym;11sl_v sl_iooutsym;
12const sl_type *sl_iotype;12const sl_type *sl_iotype;
13 13
@@ -68,9 +68,9 @@ static bool · 54 unmodified lines
68isflipped(sl_v v)68isflipped(sl_v v)
69{69{
70 bool little;70 bool little;
71 if(v == lendian)71 if(v == lendiansym)
72 little = true;72 little = true;
73 else if(v == bendian)73 else if(v == bendiansym)
74 little = false;74 little = false;
75 else75 else
76 cthrow(error(sl_errarg, "invalid endian specifier"), v);76 cthrow(error(sl_errarg, "invalid endian specifier"), v);
@@ -194,19 +194,12 @@ BUILTIN("buffer", buffer) · 117 unmodified lines
194 194
195BUILTIN("read", read)195BUILTIN("read", read)
196{196{
197 bool ws = false;197 sl_v keys[] = {wssym}, values[1];
198 if(sl_unlikely(nargs >= 2 && nargs <= 3)){198 nargs = sl_process_args(args, 0, nargs, keys, nelem(keys), values);
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];
208 if(sl_unlikely(nargs > 1))199 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];
210 USED(toio(a, true, true, false));203 USED(toio(a, true, true, false));
211 sl_gc_handle(&a);204 sl_gc_handle(&a);
212 sl_v v = sl_read_sexpr(a, ws);205 sl_v v = sl_read_sexpr(a, ws);
@@ -300,15 +293,11 @@ BUILTIN("io-peek", io_peek) · 87 unmodified lines
300 293
301BUILTIN("io-skip", io_skip)294BUILTIN("io-skip", io_skip)
302{295{
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]);
303 if(nargs != 2 && nargs != 4)299 if(nargs != 2 && nargs != 4)
304 argcount(2);300 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 }
312 ios *s = toio(args[0], true, false, false);301 ios *s = toio(args[0], true, false, false);
313 soffset off = tooffset(args[1]);302 soffset off = tooffset(args[1]);
314 soffset res = ios_skip(s, off, end);303 soffset res = ios_skip(s, off, end);
@@ -616,8 +605,8 @@ io_init(void) · 301 unmodified lines
616 wssym = mk_csym(":whitespace");605 wssym = mk_csym(":whitespace");
617 endsym = mk_csym(":end");606 endsym = mk_csym(":end");
618 ioinsym = mk_csym("*io-in*");607 ioinsym = mk_csym("*io-in*");
619 bendian = mk_csym(":big-endian");608 bendiansym = mk_csym(":big-endian");
620 lendian = mk_csym(":little-endian");609 lendiansym = mk_csym(":little-endian");
621 sl_iooutsym = mk_csym("*io-out*");610 sl_iooutsym = mk_csym("*io-out*");
622 sl_iotype = define_opaque_type(iosym, sizeof(ios), &io_vtable, nil);611 sl_iotype = define_opaque_type(iosym, sizeof(ios), &io_vtable, nil);
623 set(mk_csym("*stdout*"), cvalue_from_ref(sl_iotype, ios_stdout, sizeof(ios)));612 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
790 return v;790 return v;
791}791}
792 792
793int
794sl_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
793/*826/*
794 argument layout on stack is827 argument layout on stack is
795 |--required args--|--opt args--|--kw args--|--rest args...828 |--required args--|--opt args--|--kw args--|--rest args...
src/sl.h+3−0
@@ -140,6 +140,9 @@ enum { · 139 unmodified lines
140#define vec_type(v) (vec_elt((v), -1) & VEC_TYPE_MASK)140#define vec_type(v) (vec_elt((v), -1) & VEC_TYPE_MASK)
141#define isstruct(v) (vec_type(v) == VEC_STRUCT)141#define isstruct(v) (vec_type(v) == VEC_STRUCT)
142 142
143// supplied and non-NIL
144#define nonnil(v) ((v) != sl_unbound && (v) != sl_nil)
145
143// functions ending in _ are unsafe, faster versions146// functions ending in _ are unsafe, faster versions
144#define car_(v) (ptr(sl_cons, (v))->car)147#define car_(v) (ptr(sl_cons, (v))->car)
145#define cdr_(v) (ptr(sl_cons, (v))->cdr)148#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
227 227
228sl_v sl_list(sl_v *args, int nargs, bool star) sl_hotfn sl_nonnull(1);228sl_v sl_list(sl_v *args, int nargs, bool star) sl_hotfn sl_nonnull(1);
229sl_v sl_do_trycatch(void);229sl_v sl_do_trycatch(void);
230int sl_process_args(sl_v *args, int nreq, int nargs, const sl_v *keys, int nkeys, sl_v *values);
230int sl_process_keys(sl_v kwtable, int nreq, int nkw, int nopt, usize bp, int nargs, int va);231int sl_process_keys(sl_v kwtable, int nreq, int nkw, int nopt, usize bp, int nargs, int va);
231sl_v sl_vm_applyn(int n) sl_hotfn;232sl_v sl_vm_applyn(int n) sl_hotfn;
232sl_v sl_vm_apply_cl(int nargs) sl_hotfn;233sl_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
719 719
720BUILTIN("str->num", str_2_num)720BUILTIN("str->num", str_2_num)
721{721{
722 if(sl_unlikely(nargs != 1 && nargs != 3))722 sl_v keys[] = {basesym}, values[1];
723 argcount(2);723 nargs = sl_process_args(args, 1, nargs, keys, nelem(keys), values);
724 if(nargs != 1)
725 argcount(1);
724 char *s = tostr(args[0]), *e;726 char *s = tostr(args[0]), *e;
725 sl_v n;727 sl_v n;
726 int base = 10;728 int base = 10;
727 if(nargs == 3 && sl_unlikely(args[1] != basesym))729 if(nonnil(values[0]))
728 bthrow(error(sl_errarg, "invalid argument at position %d", 1));730 base = get_radix_arg(values[0]);
729 if(nargs == 3 && args[2] != sl_nil){731 else if(s[0] == '#'){
730 base = get_radix_arg(args[2]);
731 }else if(s[0] == '#'){
732 int c = tolower((u8int)s[1]);732 int c = tolower((u8int)s[1]);
733 if(((c == 'b' && (base = 2)) ||733 if(((c == 'b' && (base = 2)) ||
734 (c == 'o' && (base = 8)) ||734 (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