Skip to content

Commit a4ab4fe

Browse files
committed
first commit
0 parents  commit a4ab4fe

74 files changed

Lines changed: 1196 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea/
2+
*.pyc
3+
venv/
4+
*.swp

‎Makefile‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.PHONY: all clean snippets
2+
3+
PDF = icsc2020_nmeinert.pdf
4+
5+
all: $(PDF)
6+
7+
$(PDF): slides/build/main.pdf
8+
cp $< $@
9+
10+
slides/build/main.pdf: $(shell find slides -name '*.tex') $(shell find img -name '*.png') slides/beamerthemevertex.sty
11+
cd slides && mkdir -p build && \
12+
latexmk -halt-on-error -pdflatex=lualatex -pdf -jobname=build/main main.tex
13+
14+
snippets:
15+
make -f Makefile.snippets
16+
17+
clean:
18+
make clean -f Makefile.snippets
19+
rm -f slides/build/*

‎Makefile.snippets‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CPP := $(shell find snippets -name '*.cpp')
2+
TEX := $(shell \
3+
for f in `find snippets -name '*.cfg'`; do echo "$${f%.cfg}_lst.tex"; done\
4+
)
5+
6+
all: $(TEX)
7+
8+
venv: venv/bin/activate
9+
10+
venv/bin/activate: requirements.txt
11+
test -d venv || virtualenv venv
12+
. venv/bin/activate; pip install -Ur requirements.txt
13+
touch venv/bin/activate
14+
15+
snippets/snippet%_lst.tex: snippets/snippet%.cfg $(CPP) venv convert.py
16+
. venv/bin/activate; python convert.py $<
17+
18+
clean:
19+
rm -rf venv
20+
find -iname "*.pyc" -delete
21+
rm -f $(TEX)

‎README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# About
2+
Presentation material for iCSC 2020's talk "Everything you (n)ever wanted to know about C++'s Lambdas". The [slides can be found here.](icsc2020_nmeinert.pdf)
3+
4+
# Abstract
5+
From a syntactical point of view, the Lambda expression of C++ is nothing but syntactic sugar of a struct with an appropriate call operator overload. On the other hand, this simple syntax is shockingly flexible and allows powerful abstractions in a functional way, while providing elegant and easy to read code in a language that is notoriously famous for being unnecessary clunky and verbose.
6+
7+
I will give an overview about the basic syntax and best practices. I will then talk about stateful Lambdas, Lambda inheritance and their real-world applications.

‎convert.py‎

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import json
2+
import os
3+
import sys
4+
from collections import defaultdict
5+
6+
import requests
7+
8+
9+
def require(p, error_msg):
10+
if not p:
11+
print(f'Error: {error_msg}')
12+
sys.exit(1)
13+
14+
15+
def read_source(file_name):
16+
lines = open(file_name, 'r').readlines()
17+
while len(lines) > 0 and not lines[0].strip():
18+
lines = lines[1:]
19+
20+
while len(lines) > 0 and not lines[-1].strip():
21+
lines = lines[:-1]
22+
23+
return ''.join(lines)
24+
25+
26+
def read_cfg(file_name):
27+
lines = open(file_name, 'r').readlines()
28+
return defaultdict(lambda: None, json.loads(''.join(lines)))
29+
30+
31+
def truncate_source(source, max_lines=20):
32+
lines = source.split('\n')
33+
if len(lines) > max_lines + 1:
34+
lines = lines[:max_lines - 1]
35+
lines.append('[...]\n')
36+
return '\n'.join(lines)
37+
38+
39+
def compile(source, compiler, flags=None):
40+
flags = flags if flags else ''
41+
42+
filters = {
43+
'binary': False,
44+
'commentOnly': True,
45+
'demangle': True,
46+
'directives': True,
47+
'execute': False,
48+
'intel': True,
49+
'labels': True,
50+
'libraryCode': False,
51+
'trim': True,
52+
}
53+
54+
data = {
55+
'source': source,
56+
'options': {
57+
'userArguments': flags,
58+
'compilerOptions': {},
59+
'filters': filters,
60+
}
61+
}
62+
63+
url = f'https://godbolt.org/api/compiler/{compiler}/compile'
64+
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
65+
response = requests.post(url, data=json.dumps(data), headers=headers)
66+
67+
if response.status_code == 200:
68+
content = json.loads(response.content.decode('utf8'))
69+
asm = content['asm'] if 'asm' in content else []
70+
71+
lines = [f'# {compiler} {flags}', ]
72+
for line in asm:
73+
txt = line['text']
74+
src = line['source']
75+
76+
if not txt.strip().startswith('#'):
77+
n = src['line'] if src and 'line' in src else ''
78+
lines.append(f'{n:>2}| {txt}')
79+
80+
return '\n'.join(lines)
81+
return None
82+
83+
84+
def upload(source, compiler=None, flags=None, compile=True, execute=False):
85+
flags = flags if flags else ''
86+
87+
compiler_cfg = {'id': compiler, 'options': flags, }
88+
executor_cfg = {'compiler': compiler_cfg, }
89+
90+
data = {
91+
'sessions': [{
92+
'id': 1,
93+
'language': 'c++',
94+
'source': source,
95+
'compilers': [compiler_cfg, ] if compile else [],
96+
'executors': [executor_cfg, ] if execute else [],
97+
}, ],
98+
}
99+
100+
url = 'https://godbolt.org/shortener'
101+
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
102+
response = requests.post(url, data=json.dumps(data), headers=headers)
103+
if response.status_code == 200:
104+
body = json.loads(response.content.decode('utf8'))
105+
if 'url' in body:
106+
return body['url']
107+
return None
108+
109+
110+
def make_listing(source, url=None, options=None):
111+
options = options if options else []
112+
113+
if url:
114+
title = url.lstrip('http://').lstrip('https://').lstrip('www.')
115+
title = title.replace('_', r'\_')
116+
options.append(r'title=\href{' + url + r'}{\texttt{' + title + '}}')
117+
118+
tex = r'\begin{lstlisting}'
119+
tex += '[' + ','.join(options) + ']\n'
120+
tex += source.rstrip() + '\n'
121+
tex += r'\end{lstlisting}' + '\n'
122+
return tex
123+
124+
125+
if __name__ == '__main__':
126+
require(len(sys.argv) == 2, 'Usage {} [file.cfg]'.format(sys.argv[0]))
127+
128+
cfg_file = sys.argv[1]
129+
root, _ = os.path.splitext(cfg_file)
130+
require(os.path.isfile(cfg_file), f'File \'{cfg_file}\' does not exist!')
131+
132+
cfg = read_cfg(cfg_file)
133+
cpp_file = os.path.join(os.path.dirname(cfg_file), cfg['cpp_file'])
134+
require(cpp_file, 'Could not find property \'cpp_file\'!')
135+
136+
require(os.path.isfile(cpp_file), f'File \'{cpp_file}\' does not exist!')
137+
source = read_source(cpp_file)
138+
require(source, f'File \'{cpp_file}\' is empty!')
139+
140+
compiler = cfg['compiler']
141+
url = upload(source=source,
142+
compiler=compiler,
143+
flags=cfg['flags'],
144+
compile=(cfg['compile'] is True),
145+
execute=(cfg['execute'] is True))
146+
if not url:
147+
print('Error: Could not receive URL from godbold.org!')
148+
url = '???'
149+
150+
if cfg['compile'] is True:
151+
asm = compile(source=source, compiler=compiler, flags=cfg['flags'])
152+
if asm:
153+
with open(root + '_asmlst.tex', 'w') as f:
154+
if cfg['truncate'] is not False:
155+
asm = truncate_source(asm)
156+
157+
f.write(make_listing(asm, url=url, options=['language={}', 'numbers=none']))
158+
open(root + '.asm', 'w').write(asm)
159+
else:
160+
print('Error: Could not receive compilation result from godbold.org!')
161+
162+
with open(root + '_cpplst.tex', 'w') as f:
163+
if cfg['truncate'] is not False:
164+
source = truncate_source(source)
165+
166+
f.write(make_listing(source, url=url))

‎icsc2020_nmeinert.pdf‎

84.2 KB
Binary file not shown.

‎requirements.txt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
certifi==2019.9.11
2+
chardet==3.0.4
3+
idna==2.8
4+
requests==2.22.0
5+
urllib3==1.25.6

‎slides/.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
*.aux

0 commit comments

Comments
 (0)