diff --git a/.dir-locals.el b/.dir-locals.el
index 5ccc464..d84842d 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -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"))
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..88a5e0d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/ftb"]
+ path = src/ftb
+ url = https://github.com/FelixBrendel/ftb
diff --git a/bin/pre.slime b/bin/pre.slime
index 8e73699..47b4776 100644
--- a/bin/pre.slime
+++ b/bin/pre.slime
@@ -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 ()))
diff --git a/bin/tests/lexical_scope.slime b/bin/tests/lexical_scope.slime
index 65c796e..72bd244 100644
--- a/bin/tests/lexical_scope.slime
+++ b/bin/tests/lexical_scope.slime
@@ -3,8 +3,7 @@
(define (make-counter)
(let ((var 0))
(lambda ()
- (mutate var (+ 1 var))
- var)))
+ (set! var (+ 1 var)))))
(define counter1 (make-counter))
diff --git a/bin/tests/lexical_scope.slime.expanded b/bin/tests/lexical_scope.slime.expanded
index 2a3c968..26a9c39 100644
--- a/bin/tests/lexical_scope.slime.expanded
+++ b/bin/tests/lexical_scope.slime.expanded
@@ -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))
diff --git a/build.sh b/build.sh
index e7598e4..10fbafc 100755
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/profiler_vis/data.csv b/profiler_vis/data.csv
new file mode 100644
index 0000000..e249edd
--- /dev/null
+++ b/profiler_vis/data.csv
@@ -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
\ No newline at end of file
diff --git a/profiler_vis/main.py b/profiler_vis/main.py
new file mode 100644
index 0000000..e16e16d
--- /dev/null
+++ b/profiler_vis/main.py
@@ -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()
diff --git a/profiler_vis/test.py b/profiler_vis/test.py
new file mode 100644
index 0000000..745f6f0
--- /dev/null
+++ b/profiler_vis/test.py
@@ -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})
diff --git a/profiler_vis/test.rkt b/profiler_vis/test.rkt
new file mode 100644
index 0000000..937eb8f
--- /dev/null
+++ b/profiler_vis/test.rkt
@@ -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)
+
diff --git a/profiler_vis/test.svg b/profiler_vis/test.svg
new file mode 100644
index 0000000..9aad194
--- /dev/null
+++ b/profiler_vis/test.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test2.py b/profiler_vis/test2.py
new file mode 100644
index 0000000..68dd466
--- /dev/null
+++ b/profiler_vis/test2.py
@@ -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 ###############
diff --git a/profiler_vis/test_full.svg b/profiler_vis/test_full.svg
new file mode 100644
index 0000000..02552d3
--- /dev/null
+++ b/profiler_vis/test_full.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test_full2.svg b/profiler_vis/test_full2.svg
new file mode 100644
index 0000000..8021b42
--- /dev/null
+++ b/profiler_vis/test_full2.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test_p1.svg b/profiler_vis/test_p1.svg
new file mode 100644
index 0000000..c963ba2
--- /dev/null
+++ b/profiler_vis/test_p1.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test_p2.svg b/profiler_vis/test_p2.svg
new file mode 100644
index 0000000..d049b37
--- /dev/null
+++ b/profiler_vis/test_p2.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test_resources.svg b/profiler_vis/test_resources.svg
new file mode 100644
index 0000000..62e1569
--- /dev/null
+++ b/profiler_vis/test_resources.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/profiler_vis/test_weekly.svg b/profiler_vis/test_weekly.svg
new file mode 100644
index 0000000..5b56c66
--- /dev/null
+++ b/profiler_vis/test_weekly.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/defines.cpp b/src/defines.cpp
index 54b522f..7331ad5 100644
--- a/src/defines.cpp
+++ b/src/defines.cpp
@@ -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
-class defer_finalizer {
- F f;
- bool moved;
-public:
- template
- defer_finalizer(T && f_) : f(std::forward(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
- defer_finalizer operator<<(F && f) {
- return defer_finalizer(std::forward(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( \
diff --git a/src/error.cpp b/src/error.cpp
index df7155c..8bf7ef9 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -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;
diff --git a/src/eval.cpp b/src/eval.cpp
index 87ea8cb..a79b13c 100644
--- a/src/eval.cpp
+++ b/src/eval.cpp
@@ -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;
diff --git a/src/forward_decls.cpp b/src/forward_decls.cpp
index 18ad6ab..dabde4e 100644
--- a/src/forward_decls.cpp
+++ b/src/forward_decls.cpp
@@ -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;
+
}
diff --git a/src/ftb b/src/ftb
new file mode 160000
index 0000000..5d6da78
--- /dev/null
+++ b/src/ftb
@@ -0,0 +1 @@
+Subproject commit 5d6da78c90968738bcbf247530b3a3d0f095888b
diff --git a/src/io.cpp b/src/io.cpp
index 8096aae..9591ba0 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -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);
}
diff --git a/src/memory.cpp b/src/memory.cpp
index b63f717..de076e5 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -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 {
diff --git a/src/parse.cpp b/src/parse.cpp
index 4567235..1672af6 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -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
diff --git a/src/profiler.cpp b/src/profiler.cpp
new file mode 100644
index 0000000..a1de033
--- /dev/null
+++ b/src/profiler.cpp
@@ -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());
+// }
+// }
diff --git a/src/slime.h b/src/slime.h
index 63a470e..85ce1f1 100644
--- a/src/slime.h
+++ b/src/slime.h
@@ -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"
diff --git a/src/structs.cpp b/src/structs.cpp
index 3c74d22..7d9bba5 100644
--- a/src/structs.cpp
+++ b/src/structs.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,
diff --git a/src/testing.cpp b/src/testing.cpp
index b11ed0e..469ef1e 100644
--- a/src/testing.cpp
+++ b/src/testing.cpp
@@ -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();