diff --git a/benchmarks/plot_bench.py b/benchmarks/plot_bench.py new file mode 100644 index 00000000..f4f61317 --- /dev/null +++ b/benchmarks/plot_bench.py @@ -0,0 +1,44 @@ +from glob import glob +import pandas as pd +import matplotlib.pyplot as plt + +bench_files = glob('stored_results/*') +headers = ('File','Eval time (s)') + +benches = ['q2.lisp', 'fibonacci_tail.lisp', 'dec_cnt3.lisp', + 'dec_cnt1.lisp', 'fibonacci.lisp', 'tak.lisp', + 'dec_cnt2.lisp', 'insertionsort.lisp'] + +data = [] + +plt.figure(figsize=(10.0, 5.0)) # in inches! + +for bench in benches: + dict = {} + for file in bench_files: + file_info = file.split('benchresult')[1] + file_details = file_info.split('_') + df = pd.read_csv(file,index_col='File') + + date = file_details[0] + '-' + file_details[1] + '-' + file_details[2] + + if (bench in df.index): + row = df.loc[bench] + dict.update({date : row[1]}); + else: + print("missing data point ", bench, file ) + + lists = sorted(dict.items()) # sorted by key, return a list of tuples + x, y = zip(*lists) # unpack a list of pairs into two tuples + plt.plot(x, y, label=bench) + + +lgd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) +ax = plt.gca() +for tick in ax.get_xticklabels(): + tick.set_rotation(45) +plt.ylabel("Sec") +plt.grid() +plt.savefig('benchresults.png', dpi=600, bbox_extra_artists=(lgd,), bbox_inches='tight') +plt.yscale('log') +plt.savefig('benchresults_log.png', dpi=600, bbox_extra_artists=(lgd,), bbox_inches='tight') diff --git a/benchmarks/stored_results/benchresult22_02_27_20_00_58 b/benchmarks/stored_results/benchresult22_02_27_20_00_58 deleted file mode 100644 index 23956e4b..00000000 --- a/benchmarks/stored_results/benchresult22_02_27_20_00_58 +++ /dev/null @@ -1 +0,0 @@ -File, Load time (s), Eval time (s), GC avg time (us), GC min time (us), GC max time (us), GC invocations, GC least free diff --git a/benchmarks/stored_results/benchresult22_07_11_09_42_55 b/benchmarks/stored_results/benchresult22_07_11_09_42_55 new file mode 100644 index 00000000..f84f5007 --- /dev/null +++ b/benchmarks/stored_results/benchresult22_07_11_09_42_55 @@ -0,0 +1,9 @@ +File, Load time (s), Eval time (s), GC avg time (us), GC min time (us), GC max time (us), GC invocations, GC least free +q2.lisp, 0.002300000, 1.308599948, 525.423706054, 300, 600, 59, 1920 +fibonacci_tail.lisp, 0.002799999, 0.005499999, 300.000000000, 300, 300, 1, 2047 +dec_cnt3.lisp, 0.002000000, 1.081699967, 453.333343505, 300, 500, 15, 1996 +dec_cnt1.lisp, 0.001500000, 3.051199913, 488.000000000, 300, 500, 100, 2014 +fibonacci.lisp, 0.001599999, 3.199199914, 493.617034912, 300, 500, 94, 1968 +tak.lisp, 0.002600000, 2.824199914, 537.931030273, 300, 600, 203, 1854 +dec_cnt2.lisp, 0.001500000, 2.371400117, 482.000000000, 300, 500, 100, 2014 +insertionsort.lisp, 0.004499999, 0.007199999, 300.000000000, 300, 300, 1, 2047 diff --git a/include/lbm_version.h b/include/lbm_version.h index 243acd82..d70ddda6 100644 --- a/include/lbm_version.h +++ b/include/lbm_version.h @@ -29,6 +29,10 @@ /*! \page changelog Changelog +Jul 13 2022: Version 0.5.4 + - Added function that lookups based on the second field in assoc structures. + Called it "cossa" as it is like assoc but backwards. + Jul 4 2022: Version 0.5.4 - Added possibility to partially apply closures. A partially applied closure is again a closure. @@ -42,8 +46,8 @@ May 22 2022: Version 0.5.3 - Fix evaluator bug in progn that made tail-call not fire properly when there is only one expr in the progn sequence. -May 10 2022: Version 0.5.3 - - symbols starting with "ext-" will be allocated into the extensions-list +May 10 2022: Version 0.5.3 + - symbols starting with "ext-" will be allocated into the extensions-list and can on the VESC version of lispbm be dynamically bound to newly loaded extensions at runtime. @@ -54,7 +58,7 @@ May 5 2022: Version 0.5.2 - Line and column numbers associated with read errors. - More explanatory descriptions in error messages related to read errors. -May 2 2022: Version 0.5.2 +May 2 2022: Version 0.5.2 - Performance tweaks to the evaluator. Small but positive effect. May 1 2022: Version 0.5.2 diff --git a/include/symrepr.h b/include/symrepr.h index 030788f0..5817beb0 100644 --- a/include/symrepr.h +++ b/include/symrepr.h @@ -164,6 +164,7 @@ #define SYM_ASSOC 0x148 #define SYM_ACONS 0x149 #define SYM_SET_ASSOC 0x14A +#define SYM_COSSA 0x14B #define SYM_IS_FUNDAMENTAL 0x150 diff --git a/src/eval_cps.c b/src/eval_cps.c index efcbc9c9..07e664f8 100644 --- a/src/eval_cps.c +++ b/src/eval_cps.c @@ -1851,8 +1851,6 @@ static inline void cont_closure_application_args(eval_context_t *ctx) { lbm_stack_drop(&ctx->K, 5); ctx->app_cont = true; ctx->r = closure; - //lbm_set_error_reason("Too few arguments."); - //error_ctx(lbm_enc_sym(SYM_EERROR)); } else { sptr[2] = clo_env; sptr[3] = lbm_cdr(params); diff --git a/src/fundamental.c b/src/fundamental.c index 71354f0a..8f217aa5 100644 --- a/src/fundamental.c +++ b/src/fundamental.c @@ -650,6 +650,19 @@ lbm_value assoc_lookup(lbm_value key, lbm_value assoc) { return lbm_enc_sym(SYM_NO_MATCH); } +lbm_value cossa_lookup(lbm_value key, lbm_value assoc) { + lbm_value curr = assoc; + while (lbm_type_of(curr) == LBM_TYPE_CONS) { + lbm_value c = lbm_ref_cell(curr)->car; + if (struct_eq(lbm_ref_cell(c)->cdr, key)) { + return lbm_ref_cell(c)->car; + } + curr = lbm_ref_cell(curr)->cdr; + } + return lbm_enc_sym(SYM_NO_MATCH); +} + + lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) { lbm_uint result = lbm_enc_sym(SYM_EERROR); @@ -881,6 +894,22 @@ lbm_value lbm_fundamental(lbm_value* args, lbm_uint nargs, lbm_value op) { } /* else error */ } } break; + case SYM_COSSA: { + if (nargs == 2) { + if (lbm_is_list(args[0])) { + lbm_value r = cossa_lookup(args[1], args[0]); + if (lbm_is_symbol(r) && + lbm_dec_sym(r) == SYM_NO_MATCH) { + result = lbm_enc_sym(SYM_NIL); + } else { + result = r; + } + } else if (lbm_is_symbol(args[0]) && + lbm_dec_sym(args[0]) == SYM_NIL) { + result = args[0]; /* nil */ + } /* else error */ + } + } break; case SYM_ACONS: { if (nargs == 3) { lbm_value keyval = lbm_cons(args[0], args[1]); diff --git a/src/symrepr.c b/src/symrepr.c index c4fafc3f..e4ffc113 100644 --- a/src/symrepr.c +++ b/src/symrepr.c @@ -157,6 +157,7 @@ special_sym const special_symbols[] = { {"setix" , SYM_SET_IX}, {"assoc" , SYM_ASSOC}, // lookup an association + {"cossa" , SYM_COSSA}, // lookup an association "backwards" {"acons" , SYM_ACONS}, // Add to alist {"setassoc" , SYM_SET_ASSOC}, // Change association diff --git a/tests/test_cossa_0.lisp b/tests/test_cossa_0.lisp new file mode 100644 index 00000000..6eb4027c --- /dev/null +++ b/tests/test_cossa_0.lisp @@ -0,0 +1,4 @@ +(define alist (list '(1 . a) '(2 . b) '(3 . c) '(4 . d))) + +(and (eq (cossa alist 'c) 3) + (eq (cossa alist 'a) 1)) diff --git a/tests/test_cossa_1.lisp b/tests/test_cossa_1.lisp new file mode 100644 index 00000000..44b2ad06 --- /dev/null +++ b/tests/test_cossa_1.lisp @@ -0,0 +1,4 @@ +(define alist (list '(p . a) '(q . b) '(r . c) '(s . d))) + +(and (eq (cossa alist 'b) 'q) + (eq (cossa alist 'd) 's)) diff --git a/tests/test_cossa_2.lisp b/tests/test_cossa_2.lisp new file mode 100644 index 00000000..ea7e166f --- /dev/null +++ b/tests/test_cossa_2.lisp @@ -0,0 +1,7 @@ +(define alist (list '(p . a) '(q . b) '(r . c) '(s . d))) + +(setvar 'alist (acons 't 'e alist)) + +(and (eq (cossa alist 'b) 'q) + (eq (cossa alist 'd) 's) + (eq (cossa alist 'e) 't)) diff --git a/tests/test_cossa_3.lisp b/tests/test_cossa_3.lisp new file mode 100644 index 00000000..c9d718db --- /dev/null +++ b/tests/test_cossa_3.lisp @@ -0,0 +1,6 @@ +(define alist (list '(1 . a) '(2 . b) '(3 . c) '(4 . d))) + +(setassoc 'alist 3 'e) + +(and (eq (cossa alist 'c) 3) + (eq (cossa alist 'a) 1))