Ver código fonte

test out profiling

master
Felix Brendel 6 anos atrás
pai
commit
6c80382cd0
30 arquivos alterados com 565 adições e 124 exclusões
  1. +1
    -1
      .dir-locals.el
  2. +3
    -0
      .gitmodules
  3. +1
    -14
      bin/pre.slime
  4. +1
    -2
      bin/tests/lexical_scope.slime
  5. +1
    -1
      bin/tests/lexical_scope.slime.expanded
  6. +1
    -1
      build.sh
  7. +149
    -0
      profiler_vis/data.csv
  8. +27
    -0
      profiler_vis/main.py
  9. +89
    -0
      profiler_vis/test.py
  10. +21
    -0
      profiler_vis/test.rkt
  11. +2
    -0
      profiler_vis/test.svg
  12. +173
    -0
      profiler_vis/test2.py
  13. +2
    -0
      profiler_vis/test_full.svg
  14. +2
    -0
      profiler_vis/test_full2.svg
  15. +2
    -0
      profiler_vis/test_p1.svg
  16. +2
    -0
      profiler_vis/test_p2.svg
  17. +2
    -0
      profiler_vis/test_resources.svg
  18. +2
    -0
      profiler_vis/test_weekly.svg
  19. +12
    -72
      src/defines.cpp
  20. +4
    -2
      src/error.cpp
  21. +2
    -6
      src/eval.cpp
  22. +3
    -1
      src/forward_decls.cpp
  23. +1
    -0
      src/ftb
  24. +4
    -2
      src/io.cpp
  25. +0
    -2
      src/memory.cpp
  26. +26
    -18
      src/parse.cpp
  27. +17
    -0
      src/profiler.cpp
  28. +4
    -0
      src/slime.h
  29. +7
    -0
      src/structs.cpp
  30. +4
    -2
      src/testing.cpp

+ 1
- 1
.dir-locals.el Ver arquivo

@@ -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"))


+ 3
- 0
.gitmodules Ver arquivo

@@ -0,0 +1,3 @@
[submodule "src/ftb"]
path = src/ftb
url = https://github.com/FelixBrendel/ftb

+ 1
- 14
bin/pre.slime Ver arquivo

@@ -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 ()))


+ 1
- 2
bin/tests/lexical_scope.slime Ver arquivo

@@ -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
- 1
bin/tests/lexical_scope.slime.expanded Ver arquivo

@@ -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))



+ 1
- 1
build.sh Ver arquivo

@@ -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


+ 149
- 0
profiler_vis/data.csv Ver arquivo

@@ -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

+ 27
- 0
profiler_vis/main.py Ver arquivo

@@ -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()

+ 89
- 0
profiler_vis/test.py Ver arquivo

@@ -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})

+ 21
- 0
profiler_vis/test.rkt Ver arquivo

@@ -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)


+ 2
- 0
profiler_vis/test.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 173
- 0
profiler_vis/test2.py Ver arquivo

@@ -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
- 0
profiler_vis/test_full.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 2
- 0
profiler_vis/test_full2.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 2
- 0
profiler_vis/test_p1.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 2
- 0
profiler_vis/test_p2.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 2
- 0
profiler_vis/test_resources.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 2
- 0
profiler_vis/test_weekly.svg
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 12
- 72
src/defines.cpp Ver arquivo

@@ -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( \


+ 4
- 2
src/error.cpp Ver arquivo

@@ -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;


+ 2
- 6
src/eval.cpp Ver arquivo

@@ -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;


+ 3
- 1
src/forward_decls.cpp Ver arquivo

@@ -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;

}

+ 1
- 0
src/ftb

@@ -0,0 +1 @@
Subproject commit 5d6da78c90968738bcbf247530b3a3d0f095888b

+ 4
- 2
src/io.cpp Ver arquivo

@@ -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);
}


+ 0
- 2
src/memory.cpp Ver arquivo

@@ -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 {


+ 26
- 18
src/parse.cpp Ver arquivo

@@ -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


+ 17
- 0
src/profiler.cpp Ver arquivo

@@ -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());
// }
// }

+ 4
- 0
src/slime.h Ver arquivo

@@ -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"


+ 7
- 0
src/structs.cpp Ver arquivo

@@ -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,


+ 4
- 2
src/testing.cpp Ver arquivo

@@ -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();


Carregando…
Cancelar
Salvar