| @@ -26,7 +26,7 @@ | |||
| (font-lock-add-keywords | |||
| 'c++-mode | |||
| '(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\|try\\|try_void\\|without_logging\\)\\>" . | |||
| '(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\|try\\|try_void\\|ignore_logging\\|dont_break_on_errors\\)\\>" . | |||
| font-lock-keyword-face))))))) | |||
| (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) | |||
| @@ -0,0 +1,3 @@ | |||
| [submodule "src/ftb"] | |||
| path = src/ftb | |||
| url = https://github.com/FelixBrendel/ftb | |||
| @@ -120,7 +120,7 @@ condition is false." | |||
| `(,append-map (lambda (,(first body)) (list ,(rec (rest (rest (rest body)))))) ,(first (rest (rest body))))) | |||
| ((= (first body) 'if) | |||
| `(when ,(first (rest body)) ,(rec (rest (rest body))))) | |||
| ((= (first body) 'yield) | |||
| ((= (first (rest body)) 'yield) | |||
| (first (rest body))) | |||
| (else (error "Not a do-able expression")))) | |||
| @@ -158,19 +158,6 @@ ithe sequence as arguemens." | |||
| exports)))) | |||
| ;; (define-syntax (define-package name :rest body) | |||
| ;; `(define ,(string->symbol (concat-strings (symbol->string name) "->")) | |||
| ;; ((lambda () | |||
| ;; @body | |||
| ;; (set-type | |||
| ;; (special-lambda (:rest args) | |||
| ;; (let ((op (first args)) | |||
| ;; (args (rest args))) | |||
| ;; (if (callable? (eval op)) | |||
| ;; (apply op args) | |||
| ;; (eval op)))) | |||
| ;; :package))))) | |||
| (define (null? x) | |||
| "Checks if the argument is =nil=." | |||
| (= x ())) | |||
| @@ -3,8 +3,7 @@ | |||
| (define (make-counter) | |||
| (let ((var 0)) | |||
| (lambda () | |||
| (mutate var (+ 1 var)) | |||
| var))) | |||
| (set! var (+ 1 var))))) | |||
| (define counter1 (make-counter)) | |||
| @@ -1,4 +1,4 @@ | |||
| (define (make-counter) (let ((var 0)) (lambda () (mutate var (+ 1 var)) var))) | |||
| (define (make-counter) (let ((var 0)) (lambda () (set! var (+ 1 var))))) | |||
| (define counter1 (make-counter)) | |||
| @@ -4,7 +4,7 @@ pushd $SCRIPTPATH > /dev/null | |||
| # _DEBUG | |||
| # time g++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| time clang++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| time clang++ -D_DEBUG -D_PROFILING -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| echo "" | |||
| pushd ./bin > /dev/null | |||
| @@ -0,0 +1,149 @@ | |||
| nconst,character,start,end | |||
| nm0221046,Actor2,53000,237000 | |||
| nm0330687,Actor1,53000,237000 | |||
| nm0569501,Narrator,64000,237000 | |||
| nm0932891,Actor3,72000,237000 | |||
| nm3068638,Actor1 - Age 12,81000,237000 | |||
| nm2788212,Actor2 - Age 12,97000,237000 | |||
| nm1631269,Actor4,240000,424000 | |||
| nm0034309,Actor5,258000,424000 | |||
| nm1131557,Actor6,258000,424000 | |||
| nm0330687,Actor1,273000,424000 | |||
| nm0221046,Actor2,305000,424000 | |||
| nm0034309,Actor5,425000,558000 | |||
| nm0329622,Office Worker,427000,558000 | |||
| nm0330687,Actor1,427000,558000 | |||
| nm0932891,Actor3,427000,558000 | |||
| nm0381763,Actor7,433000,558000 | |||
| nm0803331,Usher,433000,558000 | |||
| nm0163988,Actor8,443000,558000 | |||
| nm0221046,Actor2,449000,558000 | |||
| nm0569501,Narrator,472000,558000 | |||
| nm0221046,Actor2,560000,647000 | |||
| nm0034309,Actor5,561000,647000 | |||
| nm0330687,Actor1,564000,647000 | |||
| nm0163988,Actor8,650000,813000 | |||
| nm0735538,Employee #1,650000,813000 | |||
| nm0330687,Actor1,652000,813000 | |||
| nm0006970,Actor9,654000,813000 | |||
| nm0803331,Usher,656000,813000 | |||
| nm0221046,Actor2,660000,813000 | |||
| nm0034309,Actor5,661000,813000 | |||
| nm0932891,Actor3,699000,813000 | |||
| nm0330687,Actor1,815000,1013000 | |||
| nm1131557,Actor6,815000,1013000 | |||
| nm0221046,Actor2,821000,1013000 | |||
| nm1631269,Actor4,865000,1013000 | |||
| nm0034309,Actor5,888000,1013000 | |||
| nm0034309,Actor5,1014000,1119000 | |||
| nm0330687,Actor1,1014000,1119000 | |||
| nm0221046,Actor2,1048000,1119000 | |||
| nm0330687,Actor1,1119000,1348000 | |||
| nm0034309,Actor5,1126000,1348000 | |||
| nm0221046,Actor2,1126000,1348000 | |||
| nm0006970,Actor9,1279000,1348000 | |||
| nm0330687,Actor1,1348000,1469000 | |||
| nm0221046,Actor2,1348000,1469000 | |||
| nm0034309,Actor5,1348000,1469000 | |||
| nm0221046/trivia,nt0447626,1377000,1469000 | |||
| nm0330687,Actor1,1470000,1619000 | |||
| nm0221046,Actor2,1471000,1619000 | |||
| nm1131557,Actor6,1547000,1619000 | |||
| nm0330687,Actor1,1622000,1839000 | |||
| nm0221046,Actor2,1627000,1839000 | |||
| nm2124215,Actor10,1752000,1839000 | |||
| nm0330687,Actor1,1839000,2006000 | |||
| nm0221046,Actor2,1839000,2006000 | |||
| nm0000148,Self,1910000,2006000 | |||
| nm0330687,Actor1,2008000,2066000 | |||
| nm0163988,Actor8,2019000,2066000 | |||
| nm1304328,New Secretary,2019000,2066000 | |||
| nm0034309,Actor5,2025000,2066000 | |||
| nm0221046,Actor2,2052000,2066000 | |||
| nm0034309,Actor5,2068000,2293000 | |||
| nm0221046,Actor2,2068000,2293000 | |||
| nm0330687,Actor1,2074000,2293000 | |||
| nm0221046,Actor2,2295000,2482000 | |||
| nm0330687,Actor1,2295000,2482000 | |||
| nm0569501,Narrator,2315000,2482000 | |||
| nm1131557,Actor6,2433000,2482000 | |||
| nm0034309,Actor5,2437000,2482000 | |||
| nm0330687,Actor1,2483000,2626000 | |||
| nm1631269,Actor4,2483000,2626000 | |||
| nm0330687/trivia,nt0127470,2539000,2626000 | |||
| nm0221046,Actor2,2557000,2626000 | |||
| nm0221046,Actor2,2630000,2853000 | |||
| nm0330687,Actor1,2630000,2853000 | |||
| nm1071303,Douche,2656000,2853000 | |||
| nm3300012,Girl on the Stairs,2835000,2853000 | |||
| nm0330687,Actor1,2853000,2984000 | |||
| nm0221046,Actor2,2861000,2984000 | |||
| nm0221046/trivia,nt0085270,2908000,2984000 | |||
| nm0221046,Actor2,2985000,3072000 | |||
| nm0330687,Actor1,2987000,3072000 | |||
| nm2622767,Actor11,3050000,3072000 | |||
| nm0330687,Actor1,3072000,3143000 | |||
| nm0221046,Actor2,3073000,3143000 | |||
| nm0221046,Actor2,3148000,3278000 | |||
| nm0330687,Actor1,3148000,3278000 | |||
| nm0897096,Actor12,3194000,3278000 | |||
| nm0533467,Actor13,3209000,3278000 | |||
| nm3505105,Actor14,3249000,3278000 | |||
| nm1304328,New Secretary,3279000,3406000 | |||
| nm0330687,Actor1,3282000,3406000 | |||
| nm0163988,Actor8,3289000,3406000 | |||
| nm0330687,Actor1,3410000,3625000 | |||
| nm0034309,Actor5,3413000,3625000 | |||
| nm0932891,Actor3,3414000,3625000 | |||
| nm0735538,Employee #1,3438000,3625000 | |||
| nm0006970,Actor9,3443000,3625000 | |||
| nm0381763,Actor7,3443000,3625000 | |||
| nm0281068,Actor15,3446000,3625000 | |||
| nm0221046,Actor2,3450000,3625000 | |||
| nm0715377,Bus Driver,3483000,3625000 | |||
| nm1036340,Actor16,3488000,3625000 | |||
| nm0330687,Actor1,3629000,3841000 | |||
| nm0034309,Actor5,3642000,3841000 | |||
| nm0221046,Actor2,3677000,3841000 | |||
| nm0006970,Actor9,3827000,3841000 | |||
| nm2306384,Minister,3827000,3841000 | |||
| nm3505110,Actor9's New Husband,3827000,3841000 | |||
| nm0221046,Actor2,3841000,3984000 | |||
| nm0006970,Actor9,3847000,3984000 | |||
| nm3505110,Actor9's New Husband,3847000,3984000 | |||
| nm0330687,Actor1,3851000,3984000 | |||
| nm3505106,Wedding Singer,3892000,3984000 | |||
| nm1131557,Actor6,3984000,4054000 | |||
| nm0034309,Actor5,3999000,4054000 | |||
| nm0163988,Actor8,4009000,4054000 | |||
| nm0330687,Actor1,4045000,4054000 | |||
| nm0330687,Actor1,4054000,4249000 | |||
| nm0569501,Narrator,4066000,4249000 | |||
| nm0221046,Actor2,4089000,4249000 | |||
| nm1656122,Partygoer,4134000,4249000 | |||
| nm1497668,Rooftop Guy #1,4168000,4249000 | |||
| nm3107009,Another Partygoer,4194000,4249000 | |||
| nm0330687,Actor1,4254000,4305000 | |||
| nm0330687,Actor1,4305000,4514000 | |||
| nm0034309,Actor5,4305000,4514000 | |||
| nm0381763,Actor7,4310000,4514000 | |||
| nm0281068,Actor10,4328000,4514000 | |||
| nm0803331,Usher,4328000,4514000 | |||
| nm0163988,Actor8,4334000,4514000 | |||
| nm0329622,Office Worker,4334000,4514000 | |||
| nm0330687/trivia,nt0127468,4362000,4514000 | |||
| nm0330687,Actor1,4516000,4740000 | |||
| nm1631269,Actor4,4520000,4740000 | |||
| nm1631269/trivia,nt0787786,4533000,4740000 | |||
| nm0221046,Actor2,4583000,4740000 | |||
| nm1071303,Douche,4593000,4740000 | |||
| nm0000163,Ben,4620000,4740000 | |||
| nm0001684,Elaine,4620000,4740000 | |||
| nm0330687,Actor1,4743000,4882000 | |||
| nm0330687/trivia,nt0920755,4751000,4882000 | |||
| nm0221046,Actor2,4851000,4882000 | |||
| nm0330687,Actor1,4885000,5228000 | |||
| nm0221046,Actor2,4907000,5228000 | |||
| nm0330687,Actor1,5230000,5426000 | |||
| nm0569501,Narrator,5240000,5426000 | |||
| nm1310368,Girl at interview,5263000,5426000 | |||
| @@ -0,0 +1,27 @@ | |||
| import plotly.figure_factory as ff | |||
| df = [ | |||
| {"Task": "call depth 4", "Start": 9321, "Finish": 9326}, | |||
| {"Task": "call depth 3", "Start": 9288, "Finish": 9311}, | |||
| {"Task": "call depth 2", "Start": 9126, "Finish": 9141}, | |||
| {"Task": "call depth 1", "Start": 9088, "Finish": 9099}, | |||
| {"Task": "call depth 0", "Start": 9076, "Finish": 9337}, | |||
| {"Task": "call depth 1", "Start": 9109, "Finish": 9179}, | |||
| {"Task": "call depth 1", "Start": 9194, "Finish": 9334}, | |||
| {"Task": "call depth 2", "Start": 9206, "Finish": 9231}, | |||
| {"Task": "call depth 2", "Start": 9237, "Finish": 9269}, | |||
| {"Task": "call depth 2", "Start": 9274, "Finish": 9331}, | |||
| {"Task": "call depth 3", "Start": 9255, "Finish": 9266}, | |||
| {"Task": "call depth 3", "Start": 9279, "Finish": 9284}, | |||
| {"Task": "call depth 4", "Start": 9299, "Finish": 9309}, | |||
| {"Task": "call depth 3", "Start": 9316, "Finish": 9329}, | |||
| ] | |||
| fig = ff.create_gantt(df, group_tasks=True, bar_width=0.4, width=1700, height=720) | |||
| fig["data"][0].update(text="apply_arguments_to_function", hoverinfo="text+x+y") | |||
| fig["data"][1].update(text="apply_arguments_to_function", hoverinfo="text+x+y") | |||
| fig["data"][2].update(text="apply_arguments_to_function", hoverinfo="text+x+y") | |||
| fig.show() | |||
| @@ -0,0 +1,89 @@ | |||
| import pandas as pd | |||
| import plotly.graph_objs as go | |||
| call_depths = [0] | |||
| datas = [] | |||
| def ensure_big_enough(list, idx, el): | |||
| l = len(list) | |||
| if (idx >= l): | |||
| list.extend([el]*(idx-l+1)) | |||
| def incr_call_depth(thread): | |||
| ensure_big_enough(call_depths, thread, 0) | |||
| call_depths[thread] += 1 | |||
| def append_to_datas(thread, data): | |||
| ensure_big_enough(datas, thread, []) | |||
| datas[thread].append(data) | |||
| with open("../bin/profiler.report", "r") as file: | |||
| for line in file: | |||
| infos = line.split() | |||
| thread = int(infos[0]) | |||
| if infos[1] == "->": | |||
| incr_call_depth(thread) | |||
| append_to_datas(thread, { | |||
| "task": f"[T{thread}] - {'{:03d}'.format(call_depths[thread])}", | |||
| "start": int(infos[5]), | |||
| "end": None | |||
| }) | |||
| elif infos[1] == "<-": | |||
| call_depths[thread] -= 1 | |||
| for set in datas[thread][::-1]: | |||
| if set["end"] == None: | |||
| set["end"] = int(infos[2]) | |||
| break | |||
| else: | |||
| print("couldn't find task that finished") | |||
| break | |||
| else: | |||
| print("neither -> nor <-") | |||
| fig = go.Figure( | |||
| layout = { | |||
| 'barmode': 'stack', | |||
| "dragmode" : "pan", | |||
| } | |||
| ) | |||
| flat_datas= [item for sublist in datas for item in sublist] | |||
| # i = 1 | |||
| # df = flat_datas[:20] | |||
| # for call in df: | |||
| # name = call["task"] | |||
| # start = call["start"] | |||
| # end = call["end"] | |||
| # duration = end,start | |||
| # fig.add_bar(x=(i,duration), | |||
| # y=(i,name), | |||
| # base=(i,start), | |||
| # orientation='h', | |||
| # showlegend=False, | |||
| # name=name, | |||
| # hovertext=f"yes", | |||
| # text="" | |||
| # ) | |||
| # i += 1 | |||
| df = pd.DataFrame(flat_datas[:20]) | |||
| df['duration'] = df['end'] - df['start'] | |||
| for stackdepth, stackdepth_df in df.groupby('task'): | |||
| params = {"x": stackdepth_df.duration, | |||
| "y": stackdepth_df.task, | |||
| "name": stackdepth, | |||
| "base": stackdepth_df.start | |||
| } | |||
| print(params) | |||
| fig.add_bar(**params, | |||
| orientation='h', | |||
| showlegend=False, | |||
| hovertext=f"yes", | |||
| text="" | |||
| ) | |||
| fig.show(config={'scrollZoom': True}) | |||
| @@ -0,0 +1,21 @@ | |||
| #lang racket | |||
| (require racket/gui mrlib/snip-canvas plot) | |||
| (define ((make-current-value-renderer fn) snip event x y) | |||
| (define overlays | |||
| (and x y (eq? (send event get-event-type) 'motion) | |||
| (list (vrule x #:style 'long-dash) | |||
| (point-label (vector x (fn x)) #:anchor 'auto)))) | |||
| (send snip set-overlay-renderers overlays)) | |||
| (define (make-plot-snip width height) | |||
| (define snip (plot-snip (function sin) | |||
| #:x-min 0 #:x-max (* 2 pi) #:y-min -1.5 #:y-max 1.5 | |||
| #:width width #:height height)) | |||
| (send snip set-mouse-event-callback (make-current-value-renderer sin)) | |||
| snip) | |||
| (define toplevel (new frame% [label "Plot"] [width 500] [height 200])) | |||
| (define canvas (new snip-canvas% [parent toplevel] [make-snip make-plot-snip])) | |||
| (send toplevel show #t) | |||
| @@ -0,0 +1,173 @@ | |||
| #!/usr/bin/env python3 | |||
| # -*- coding: utf-8-unix -*- | |||
| import datetime | |||
| import gantt | |||
| # Change font default | |||
| gantt.define_font_attributes(fill='black', | |||
| stroke='black', | |||
| stroke_width=0, | |||
| font_family="Verdana") | |||
| # Add vacations for everyone | |||
| gantt.add_vacations(datetime.date(2014, 12, 25)) | |||
| gantt.add_vacations(datetime.date(2015, 1, 1)) | |||
| gantt.add_vacations(datetime.date(2015, 1, 13)) | |||
| # Create two resources | |||
| rANO = gantt.Resource('ANO') | |||
| rJLS = gantt.Resource('JLS') | |||
| # Add vacations for one lucky resource | |||
| rANO.add_vacations( | |||
| dfrom=datetime.date(2014, 12, 29), | |||
| dto=datetime.date(2015, 1, 4) | |||
| ) | |||
| rANO.add_vacations( | |||
| dfrom=datetime.date(2015, 1, 6), | |||
| dto=datetime.date(2015, 1, 8) | |||
| ) | |||
| # Test if this resource is avalaible for some dates | |||
| print(rANO.is_available(datetime.date(2015, 1, 5))) | |||
| print(rANO.is_available(datetime.date(2015, 1, 8))) | |||
| print(rANO.is_available(datetime.date(2015, 1, 6))) | |||
| print(rANO.is_available(datetime.date(2015, 1, 2))) | |||
| print(rANO.is_available(datetime.date(2015, 1, 1))) | |||
| # Create some tasks | |||
| t1 = gantt.Task(name='tache1', | |||
| start=datetime.date(2014, 12, 25), | |||
| duration=4, | |||
| percent_done=44, | |||
| resources=[rANO], | |||
| color="#FF8080") | |||
| t2 = gantt.Task(name='tache2', | |||
| start=datetime.date(2014, 12, 28), | |||
| duration=6, | |||
| resources=[rJLS]) | |||
| t7 = gantt.Task(name='tache7', | |||
| start=datetime.date(2014, 12, 28), | |||
| duration=5, | |||
| percent_done=50) | |||
| t3 = gantt.Task(name='tache3', | |||
| start=datetime.date(2014, 12, 25), | |||
| duration=4, | |||
| depends_of=[t1, t7, t2], | |||
| resources=[rJLS]) | |||
| t4 = gantt.Task(name='tache4', | |||
| start=datetime.date(2015, 1, 1), | |||
| duration=4, | |||
| depends_of=t1, | |||
| resources=[rJLS]) | |||
| t5 = gantt.Task(name='tache5', | |||
| start=datetime.date(2014, 12, 23), | |||
| duration=3) | |||
| t6 = gantt.Task(name='tache6', | |||
| start=datetime.date(2014, 12, 25), | |||
| duration=4, | |||
| depends_of=t7, | |||
| resources=[rANO]) | |||
| t8 = gantt.Task(name='tache8', | |||
| start=datetime.date(2014, 12, 25), | |||
| duration=4, | |||
| depends_of=t7, | |||
| resources=[rANO, rJLS]) | |||
| # Create a project | |||
| p1 = gantt.Project(name='Projet 1') | |||
| # Add tasks to this project | |||
| p1.add_task(t1) | |||
| p1.add_task(t7) | |||
| p1.add_task(t2) | |||
| p1.add_task(t3) | |||
| p1.add_task(t5) | |||
| p1.add_task(t8) | |||
| # Create another project | |||
| p2 = gantt.Project(name='Projet 2', color='#FFFF40') | |||
| # Add tasks to this project | |||
| p2.add_task(t2) | |||
| p2.add_task(t4) | |||
| # Create another project | |||
| p = gantt.Project(name='Gantt') | |||
| # wich contains the first two projects | |||
| # and a single task | |||
| p.add_task(p1) | |||
| p.add_task(p2) | |||
| p.add_task(t6) | |||
| # Test cases for milestones | |||
| # Create another project | |||
| ptcm = gantt.Project(name='Test case for milestones') | |||
| tcm11 = gantt.Task(name='tcm11', | |||
| start=datetime.date(2014, 12, 25), | |||
| duration=4) | |||
| tcm12 = gantt.Task(name='tcm12', | |||
| start=datetime.date(2014, 12, 26), | |||
| duration=5) | |||
| ms1 = gantt.Milestone(name=' ', | |||
| depends_of=[tcm11, tcm12]) | |||
| tcm21 = gantt.Task(name='tcm21', | |||
| start=datetime.date(2014, 12, 30), | |||
| duration=4, | |||
| depends_of=[ms1]) | |||
| tcm22 = gantt.Task(name='tcm22', | |||
| start=datetime.date(2014, 12, 30), | |||
| duration=6, | |||
| depends_of=[ms1]) | |||
| ms2 = gantt.Milestone(name='MS2', | |||
| depends_of=[ms1, tcm21, tcm22]) | |||
| tcm31 = gantt.Task(name='tcm31', | |||
| start=datetime.date(2014, 12, 30), | |||
| duration=6, | |||
| depends_of=[ms2]) | |||
| ms3 = gantt.Milestone(name='MS3', depends_of=[ms1]) | |||
| ptcm.add_task(tcm11) | |||
| ptcm.add_task(tcm12) | |||
| ptcm.add_task(ms1) | |||
| ptcm.add_task(tcm21) | |||
| ptcm.add_task(tcm22) | |||
| ptcm.add_task(ms2) | |||
| ptcm.add_task(tcm31) | |||
| ptcm.add_task(ms3) | |||
| p.add_task(ptcm) | |||
| ##########################$ MAKE DRAW ############### | |||
| p.make_svg_for_tasks(filename='test_full.svg', | |||
| today=datetime.date(2014, 12, 31), | |||
| start=datetime.date(2014, 8, 22), | |||
| end=datetime.date(2015, 1, 14)) | |||
| p.make_svg_for_tasks(filename='test_full2.svg', | |||
| today=datetime.date(2014, 12, 31)) | |||
| p.make_svg_for_tasks(filename='test.svg', | |||
| today=datetime.date(2014, 12, 31), | |||
| start=datetime.date(2015, 1, 3), | |||
| end=datetime.date(2015, 1, 6)) | |||
| p1.make_svg_for_tasks(filename='test_p1.svg', | |||
| today=datetime.date(2014, 12, 31)) | |||
| p2.make_svg_for_tasks(filename='test_p2.svg', | |||
| today=datetime.date(2014, 12, 31)) | |||
| p.make_svg_for_resources(filename='test_resources.svg', | |||
| today=datetime.date(2014, 12, 31), | |||
| resources=[rANO, rJLS]) | |||
| p.make_svg_for_tasks(filename='test_weekly.svg', | |||
| today=datetime.date(2014, 12, 31), | |||
| scale=gantt.DRAW_WITH_WEEKLY_SCALE) | |||
| ##########################$ /MAKE DRAW ############### | |||
| @@ -2,42 +2,26 @@ | |||
| #define proc auto | |||
| #ifdef _DEBUG | |||
| constexpr bool is_debug_build = true; | |||
| # define if_debug if constexpr (true) | |||
| #else | |||
| constexpr bool is_debug_build = false; | |||
| # define if_debug if constexpr (false) | |||
| #endif | |||
| #define if_debug if constexpr (is_debug_build) | |||
| #ifdef _MSC_VER | |||
| # define if_windows if constexpr (1) | |||
| # define if_linux if constexpr (0) | |||
| # define debug_break() if_debug __debugbreak() | |||
| # define if_windows if constexpr (true) | |||
| # define if_linux if constexpr (false) | |||
| #else | |||
| # define debug_break() if_debug raise(SIGTRAP) | |||
| # define if_windows if (0) | |||
| # define if_linux if (1) | |||
| # define if_windows if constexpr (false) | |||
| # define if_linux if constexpr (true) | |||
| #endif | |||
| #define concat_( a, b) a##b | |||
| #define label(prefix, lnum) concat_(prefix,lnum) | |||
| #define try \ | |||
| if (1) \ | |||
| goto label(body,__LINE__); \ | |||
| else \ | |||
| while (1) \ | |||
| if (1) { \ | |||
| if (Globals::error) { \ | |||
| if (Globals::log_level == Log_Level::Debug) { \ | |||
| printf("in %s:%d\n", __FILE__, __LINE__); \ | |||
| } \ | |||
| return 0; \ | |||
| } \ | |||
| break; \ | |||
| } \ | |||
| else label(body,__LINE__): | |||
| #define try_void \ | |||
| #define try_or_else_return(val) \ | |||
| if (1) \ | |||
| goto label(body,__LINE__); \ | |||
| else \ | |||
| @@ -47,30 +31,17 @@ constexpr bool is_debug_build = false; | |||
| if (Globals::log_level == Log_Level::Debug) { \ | |||
| printf("in %s:%d\n", __FILE__, __LINE__); \ | |||
| } \ | |||
| return; \ | |||
| return val; \ | |||
| } \ | |||
| break; \ | |||
| } \ | |||
| else label(body,__LINE__): | |||
| ; | |||
| #define without_logging \ | |||
| if (0) \ | |||
| label(finished,__LINE__): ; \ | |||
| else \ | |||
| for (Log_Level log_level_before = Globals::log_level;;) \ | |||
| for(Globals::log_level = Log_Level::None;;) \ | |||
| if (1) { \ | |||
| goto label(body,__LINE__); \ | |||
| } \ | |||
| else \ | |||
| while (1) \ | |||
| if (1) { \ | |||
| Globals::log_level = log_level_before; \ | |||
| goto label(finished,__LINE__); \ | |||
| } \ | |||
| else label(body,__LINE__): | |||
| #define try_void try_or_else_return() | |||
| #define try try_or_else_return(0) | |||
| #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false) | |||
| #define ignore_logging fluid_let(Globals::log_level, Log_Level::None) | |||
| #define define_array_list(type, name) \ | |||
| @@ -170,39 +141,8 @@ constexpr bool is_debug_build = false; | |||
| } | |||
| template<typename F> | |||
| class defer_finalizer { | |||
| F f; | |||
| bool moved; | |||
| public: | |||
| template<typename T> | |||
| defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { } | |||
| defer_finalizer(const defer_finalizer &) = delete; | |||
| defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) { | |||
| other.moved = true; | |||
| } | |||
| ~defer_finalizer() { | |||
| if (!moved) f(); | |||
| } | |||
| }; | |||
| struct { | |||
| template<typename F> | |||
| defer_finalizer<F> operator<<(F && f) { | |||
| return defer_finalizer<F>(std::forward<F>(f)); | |||
| } | |||
| } deferrer; | |||
| #define TOKENPASTE(x, y) x ## y | |||
| #define TOKENPASTE2(x, y) TOKENPASTE(x, y) | |||
| #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&] | |||
| /* | |||
| Usage of the create_error_macros: | |||
| */ | |||
| #define __create_error(keyword, ...) \ | |||
| create_error( \ | |||
| @@ -8,12 +8,14 @@ proc delete_error() -> void { | |||
| } | |||
| proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void { | |||
| if (Globals::log_level > Log_Level::None) | |||
| printf("Error created in:\n%s:%d\n", c_file_name, c_file_line); | |||
| delete_error(); | |||
| debug_break(); | |||
| if (Globals::breaking_on_errors) { | |||
| debug_break(); | |||
| } | |||
| // visualize_lisp_machine(); | |||
| using Globals::error; | |||
| @@ -1,4 +1,6 @@ | |||
| proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> Lisp_Object* { | |||
| profile_this; | |||
| Environment* new_env; | |||
| try new_env = Memory::create_child_environment(function->parent_environment); | |||
| push_environment(new_env); | |||
| @@ -17,10 +19,6 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> | |||
| create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i); | |||
| return; | |||
| } | |||
| // TODO(Felix): here we create new lisp_object_symbols from | |||
| // their identifiers but before we converted them to | |||
| // strings from symbols... Wo maybe just use the symbols? | |||
| // NOTE(Felix): We have to copy all the arguments, otherwise | |||
| // we change the program code. | |||
| try_void sym = function->positional_arguments->symbols[i]; | |||
| @@ -527,8 +525,6 @@ proc interprete_stdin() -> void { | |||
| return; | |||
| } | |||
| Parser::environment_for_macros = user_env; | |||
| printf("Welcome to the lispy interpreter.\n"); | |||
| char* line; | |||
| @@ -30,7 +30,7 @@ namespace Memory { | |||
| } | |||
| namespace Parser { | |||
| extern Environment* environment_for_macros; | |||
| // extern Environment* environment_for_macros; | |||
| extern String* standard_in; | |||
| extern String* parser_file; | |||
| @@ -46,5 +46,7 @@ namespace Globals { | |||
| Environment_Array_List* envi_stack = create_Environment_array_list(); | |||
| } | |||
| bool breaking_on_errors = true; | |||
| Error* error = nullptr; | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| Subproject commit 5d6da78c90968738bcbf247530b3a3d0f095888b | |||
| @@ -295,8 +295,10 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v | |||
| fputs(Memory::get_c_str(node->value.string), file); | |||
| } break; | |||
| case (Lisp_Object_Type::Vector): { | |||
| fputs("[vector", file); | |||
| for (int i = 0; i < node->value.vector.length; ++i) { | |||
| fputs("[", file); | |||
| if (node->value.vector.length > 0) | |||
| print(node->value.vector.data); | |||
| for (int i = 1; i < node->value.vector.length; ++i) { | |||
| fputs(" ", file); | |||
| print(node->value.vector.data+i); | |||
| } | |||
| @@ -402,8 +402,6 @@ namespace Memory { | |||
| load_built_ins_into_environment(); | |||
| Parser::environment_for_macros = ret; | |||
| // save the current working directory | |||
| char* cwd = get_cwd(); | |||
| defer { | |||
| @@ -4,23 +4,31 @@ namespace Parser { | |||
| int parser_line; | |||
| int parser_col; | |||
| // NOTE(Felix): In this environment, the build in functions will | |||
| // be loaded, and the macros will be stored in form of | |||
| // special-lambdas, that get executed in this environment at | |||
| // read-time. This should always be the global environment. | |||
| Environment* environment_for_macros; | |||
| // proc set_environment_for_macros(Environment* env) -> void { | |||
| // // NOTE(Felix): it is important to keep the parser environment | |||
| // // up to date with the global environment. When doing tests, | |||
| // // or running a programm we have to reload it. | |||
| // // NOTE(Felix): For now we just allow executing built-ins at | |||
| // // read-time (while creating macros). If later we want to | |||
| // // change that, we have to define some funcions in this | |||
| // // environment. | |||
| // environment_for_macros = env; | |||
| // } | |||
| proc maybe_expand_reader_macro() -> Lisp_Object* { | |||
| // static Lisp_Object* quote_sym = Memory::get_or_create_lisp_object_symbol("quote"); | |||
| // static Lisp_Object* qquote_sym = Memory::get_or_create_lisp_object_symbol("quasiquote"); | |||
| // static Lisp_Object* unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote"); | |||
| // static Lisp_Object* us_sym = Memory::get_or_create_lisp_object_symbol("unquote-splicing"); | |||
| // if (text[*index_in_text] == '\'') { | |||
| // *index_in_text++; | |||
| // return quote_sym; | |||
| // } | |||
| // if (text[*index_in_text] == '`') { | |||
| // *index_in_text++; | |||
| // return qquote_sym; | |||
| // } | |||
| // if (text[*index_in_text] == ',') { | |||
| // *index_in_text++; | |||
| // return unquote_sym; | |||
| // } | |||
| // if (text[*index_in_text] == ',' && text[*index_in_text] == '@') { | |||
| // *index_in_text += 2; | |||
| // return us_sym; | |||
| // } | |||
| return nullptr; | |||
| } | |||
| proc inject_scl(Lisp_Object* lo) -> void { | |||
| lo->sourceCodeLocation = new(Source_Code_Location); | |||
| @@ -387,7 +395,7 @@ namespace Parser { | |||
| Lisp_Object* macro; | |||
| try macro = Memory::create_lisp_object(); | |||
| Memory::set_type(macro, Lisp_Object_Type::Function); | |||
| macro->value.function.parent_environment = environment_for_macros; | |||
| macro->value.function.parent_environment = get_current_environment(); | |||
| macro->value.function.type = Function_Type::Macro; | |||
| // if parameters were specified | |||
| @@ -0,0 +1,17 @@ | |||
| // namespace Profiler { | |||
| // proc init() -> void { | |||
| // out_file = fopen("profiler.report", "w"); | |||
| // if (!out_file) | |||
| // create_generic_error("couldnt create prfiler file."); | |||
| // } | |||
| // proc exit() -> void { | |||
| // fclose(out_file); | |||
| // } | |||
| // proc log_entry(const char* func, const char* file, int line) -> void { | |||
| // fprintf(out_file,"%d -> %s %s %d %ld\n", Globals::thread_type, func, file, line, clock()); | |||
| // } | |||
| // proc log_exit() -> void { | |||
| // fprintf(out_file, "%d <- %ld\n", Globals::thread_type, clock()); | |||
| // } | |||
| // } | |||
| @@ -24,11 +24,15 @@ | |||
| #undef _CRT_SECURE_NO_DEPRECATE | |||
| #undef _CRT_SECURE_NO_WARNINGS | |||
| #include "./ftb/macros.h" | |||
| #include "./ftb/profiler.hpp" | |||
| namespace Slime { | |||
| # include "./defines.cpp" | |||
| # include "./platform.cpp" | |||
| # include "./structs.cpp" | |||
| # include "./forward_decls.cpp" | |||
| # include "./profiler.cpp" | |||
| # include "./memory.cpp" | |||
| # include "./lisp_object.cpp" | |||
| # include "./error.cpp" | |||
| @@ -8,6 +8,13 @@ define_array_list(String*, String); | |||
| define_array_list(int, Int); | |||
| define_array_list(void*, Void_Ptr); | |||
| enum struct Thread_Type { | |||
| Main, | |||
| GarbageCollection | |||
| }; | |||
| enum struct Lisp_Object_Type { | |||
| Nil, | |||
| T, | |||
| @@ -517,8 +517,10 @@ proc test_built_in_type() -> testresult { | |||
| char exp_string3[] = "(begin (set-type a \"wrong tpye\")(type a))"; | |||
| expression = Parser::parse_single_expression(exp_string3); | |||
| without_logging { | |||
| result = eval_expr(expression); | |||
| ignore_logging { | |||
| dont_break_on_errors { | |||
| result = eval_expr(expression); | |||
| } | |||
| } | |||
| assert_error(); | |||