Skip to content

Commit a980d6c

Browse files
authored
Pretty good chance I upload this to pypi now...
1 parent 8da1ec2 commit a980d6c

27 files changed

Lines changed: 2751 additions & 2404 deletions

pyparse/C_compiler.py

Lines changed: 132 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
1+
from typing import Optional
12

2-
from .constants import *
3-
from .compilator import Compilation, ICompilerOptions, Node
3+
from .compilator import Compilation, ICompilerOptions, Node
4+
from .constants import *
45
from .frontend import IFrontendResult
56

67

7-
from typing import Optional
8-
98
class CCompiler:
109
"""The Final HeadPeice where the Main C-Code gets compiled to..."""
11-
def __init__(self,header:Optional[str] = None,debug:Optional[str] = None) -> None:
12-
# NOTE Unlike in typescript llparse Containers are not Required since I'm using a different methoad to translate those parts...
13-
self.options = ICompilerOptions(debug,header)
1410

15-
def compile(self,info:IFrontendResult):
16-
compilation = Compilation(info.prefix,info.properties,list(info.resumptionTargets),
17-
options=self.options)
11+
def __init__(
12+
self, header: Optional[str] = None, debug: Optional[str] = None
13+
) -> None:
14+
# NOTE Unlike in typescript llparse Containers are not Required since I'm using a different methoad to translate those parts...
15+
self.options = ICompilerOptions(debug, header)
1816

17+
def compile(self, info: IFrontendResult):
18+
compilation = Compilation(
19+
info.prefix,
20+
info.properties,
21+
list(info.resumptionTargets),
22+
options=self.options,
23+
)
1924

20-
out:list[str] = []
21-
22-
out.append('#include <stdlib.h>')
23-
out.append('#include <stdint.h>')
24-
out.append('#include <string.h>')
25-
out.append('')
25+
out: list[str] = []
2626

27+
out.append("#include <stdlib.h>")
28+
out.append("#include <stdint.h>")
29+
out.append("#include <string.h>")
30+
out.append("")
31+
# Seems LLParse was updated from /* UNREACHABLE */ abort(); to a Macro, Intresting...
2732
out.append('#ifdef __SSE4_2__')
2833
out.append(' #ifdef _MSC_VER')
2934
out.append(' #include <nmmintrin.h>')
@@ -33,155 +38,167 @@ def compile(self,info:IFrontendResult):
3338
out.append('#endif /* __SSE4_2__ */')
3439
out.append('')
3540

36-
41+
out.append('#ifdef __ARM_NEON__')
42+
out.append(' #include <arm_neon.h>')
43+
out.append('#endif /* __ARM_NEON__ */')
44+
out.append('')
45+
46+
out.append('#ifdef __wasm__')
47+
out.append(' #include <wasm_simd128.h>')
48+
out.append('#endif /* __wasm__ */')
49+
out.append('')
50+
3751
out.append('#ifdef _MSC_VER')
3852
out.append(' #define ALIGN(n) _declspec(align(n))')
53+
out.append(' #define UNREACHABLE __assume(0)')
3954
out.append('#else /* !_MSC_VER */')
4055
out.append(' #define ALIGN(n) __attribute__((aligned(n)))')
56+
out.append(' #define UNREACHABLE __builtin_unreachable()')
4157
out.append('#endif /* _MSC_VER */')
4258

43-
44-
out.append('')
45-
out.append(f'#include "{self.options.header if self.options.header else info.prefix}.h"')
46-
out.append(f'')
47-
out.append(f'typedef int (*{info.prefix}__span_cb)(')
48-
out.append(f' {info.prefix}_t*, const char*, const char*);')
49-
out.append('')
59+
out.append("")
60+
out.append(
61+
f'#include "{self.options.header if self.options.header else info.prefix}.h"'
62+
)
63+
out.append("")
64+
out.append(f"typedef int (*{info.prefix}__span_cb)(")
65+
out.append(f" {info.prefix}_t*, const char*, const char*);")
66+
out.append("")
5067

5168
# Start Queuing span callbacks
52-
# otherwise we will have nothing
53-
# but mess which is not what we want - Vizonex
69+
# otherwise we will have nothing
70+
# but mess which is not what we want - Vizonex
5471
compilation.reserveSpans(info.spans)
55-
56-
57-
58-
rootState : Node = compilation.unwrapNode(info.root)
72+
73+
rootState: Node = compilation.unwrapNode(info.root)
5974
rootName = rootState.build(compilation)
6075
# Bring in the rest of the variables...
6176
compilation.buildGlobals(out)
6277
out.append("")
6378

64-
out.append(f'int {info.prefix}_init({info.prefix}_t* {ARG_STATE}) '+'{')
65-
out.append(f' memset({ARG_STATE}, 0, sizeof(*{ARG_STATE}));')
66-
out.append(f' {ARG_STATE}->_current = (void*) (intptr_t) {rootName};')
67-
out.append(f' return 0;')
68-
out.append('}')
69-
out.append('')
79+
out.append(f"int {info.prefix}_init({info.prefix}_t* {ARG_STATE}) " + "{")
80+
out.append(f" memset({ARG_STATE}, 0, sizeof(*{ARG_STATE}));")
81+
out.append(f" {ARG_STATE}->_current = (void*) (intptr_t) {rootName};")
82+
out.append(" return 0;")
83+
out.append("}")
84+
out.append("")
7085

71-
out.append(f'static llparse_state_t {info.prefix}__run(')
72-
out.append(f' {info.prefix}_t* {ARG_STATE},')
73-
out.append(f' const unsigned char* {ARG_POS},')
74-
out.append(f' const unsigned char* {ARG_ENDPOS}) '+'{')
75-
out.append(f' int {VAR_MATCH};')
76-
out.append(' switch ((llparse_state_t) (intptr_t) ' +
77-
f'{compilation.currentField()}) '+'{')
86+
# TODO (Vizonex) Make llparse_state_t's Name Optional and alterable incase mixed with
87+
# llhttp or another parser
88+
out.append(f"static llparse_state_t {info.prefix}__run(")
89+
out.append(f" {info.prefix}_t* {ARG_STATE},")
90+
out.append(f" const unsigned char* {ARG_POS},")
91+
out.append(f" const unsigned char* {ARG_ENDPOS}) " + "{")
92+
out.append(f" int {VAR_MATCH};")
93+
out.append(
94+
" switch ((llparse_state_t) (intptr_t) "
95+
+ f"{compilation.currentField()}) "
96+
+ "{"
97+
)
7898

7999
# Now build resumption states... These are states what will have a 'case block' next to them...
80-
# However I'm not refering to the characters those will be handles in thier inner switches,
81-
# I'm talking about the major states...
100+
# However I'm not refering to the characters those will be handles in thier inner switches,
101+
# I'm talking about the major states...
82102
tmp = []
83103
compilation.buildResumptionStates(tmp)
84-
compilation.indent(out,tmp,' ')
85-
104+
compilation.indent(out, tmp, " ")
105+
86106
# Final Resumption State... Very important!
87-
out.append(' default:')
88-
out.append(' /* UNREACHABLE */')
89-
out.append(' abort();')
90-
out.append(' }')
107+
out.append(" default:")
108+
out.append(" UNREACHABLE;")
109+
out.append(" }")
91110

92-
93111
tmp = []
94112
compilation.buildInternalStates(tmp)
95-
compilation.indent(out, tmp, ' ')
113+
compilation.indent(out, tmp, " ")
96114

97-
out.append('}')
98-
out.append('')
99-
100-
101-
102-
out.append(f'int {info.prefix}_execute({info.prefix}_t* {ARG_STATE}, ' +
103-
f'const char* {ARG_POS}, const char* {ARG_ENDPOS}) '+'{');
104-
out.append(' llparse_state_t next;')
105-
out.append('')
115+
out.append("}")
116+
out.append("")
106117

107-
out.append(' /* check lingering errors */')
108-
out.append(f' if ({compilation.errorField()} != 0) '+'{')
109-
out.append(f' return {compilation.errorField()};')
110-
out.append(' }')
111-
out.append('')
118+
out.append(
119+
f"int {info.prefix}_execute({info.prefix}_t* {ARG_STATE}, "
120+
+ f"const char* {ARG_POS}, const char* {ARG_ENDPOS}) "
121+
+ "{"
122+
)
123+
out.append(" llparse_state_t next;")
124+
out.append("")
112125

126+
out.append(" /* check lingering errors */")
127+
out.append(f" if ({compilation.errorField()} != 0) " + "{")
128+
out.append(f" return {compilation.errorField()};")
129+
out.append(" }")
130+
out.append("")
113131

114132
tmp = []
115-
self.restartSpans(compilation,info, tmp)
116-
compilation.indent(out,tmp,' ')
133+
self.restartSpans(compilation, info, tmp)
134+
compilation.indent(out, tmp, " ")
117135
args = [
118-
compilation.stateArg(),
119-
f'(const unsigned char*) {compilation.posArg()}',
120-
f'(const unsigned char*) {compilation.endPosArg()}',
136+
compilation.stateArg(),
137+
f"(const unsigned char*) {compilation.posArg()}",
138+
f"(const unsigned char*) {compilation.endPosArg()}",
121139
]
122140
out.append(f" next = {info.prefix}__run({(', ').join(args)});")
123-
out.append(f' if (next == {STATE_ERROR}) '+'{')
124-
out.append(f' return {compilation.errorField()};')
125-
out.append(' }')
126-
out.append(f' {compilation.currentField()} = (void*) (intptr_t) next;')
127-
out.append('')
141+
out.append(f" if (next == {STATE_ERROR}) " + "{")
142+
out.append(f" return {compilation.errorField()};")
143+
out.append(" }")
144+
out.append(f" {compilation.currentField()} = (void*) (intptr_t) next;")
145+
out.append("")
128146

129147
tmp = []
130148
self.executeSpans(compilation, info, tmp)
131-
compilation.indent(out, tmp, ' ')
149+
compilation.indent(out, tmp, " ")
132150

133-
out.append(' return 0;')
134-
out.append('}')
151+
out.append(" return 0;")
152+
out.append("}")
135153

136154
# JOIN ALL OF THEM!
137155
return "\n".join(out)
138156

139-
def restartSpans(self,ctx:Compilation, info:IFrontendResult,out:list[str]):
157+
def restartSpans(self, ctx: Compilation, info: IFrontendResult, out: list[str]):
140158
if len(info.spans) == 0:
141-
return
142-
159+
return
160+
143161
out.append("/* restart spans */")
144162
for span in info.spans:
145163
posField = ctx.spanPosField(span.index)
146-
147-
out.append(f'if ({posField} != NULL) '+'{')
148-
out.append(f' {posField} = (void*) {ctx.posArg()};')
149-
out.append('}')
150-
out.append('')
151164

152-
# LAST ONE...
153-
def executeSpans(self,ctx:Compilation,info:IFrontendResult,out:list[str]):
154-
if len(info.spans) == 0:
155-
return
156-
165+
out.append(f"if ({posField} != NULL) " + "{")
166+
out.append(f" {posField} = (void*) {ctx.posArg()};")
167+
out.append("}")
168+
out.append("")
169+
170+
def executeSpans(self, ctx: Compilation, info: IFrontendResult, out: list[str]):
171+
if not info.spans:
172+
return
173+
157174
out.append("/* execute spans */")
158175
for span in info.spans:
159176
posField = ctx.spanPosField(span.index)
160-
177+
161178
if len(span.callbacks) == 1:
162-
cb = ctx.unwrapCode(span.callbacks[0],True)
179+
cb = ctx.unwrapCode(span.callbacks[0], True)
163180
callback = ctx.buildCode(cb)
164-
181+
165182
else:
166-
# TODO (Vizonex) Merge lines 139 & 140 together in a future update
167-
callback = f'({info.prefix}__span_cb)' + ctx.spanCbField(span.index)
168-
callback = f'({callback})'
169-
170-
args = [
171-
ctx.stateArg(),posField,f'(const char*) {ctx.endPosArg()}'
172-
]
173-
174-
out.append(f'if ({posField} != NULL) '+'{')
175-
out.append(' int error;')
176-
out.append('')
183+
# TODO (Vizonex) Merge lines 139 & 140 together in a future update
184+
callback = (
185+
f"({info.prefix}__span_cb)"
186+
+ ctx.spanCbField(span.index)
187+
+ f"({callback})"
188+
)
189+
190+
args = [ctx.stateArg(), posField, f"(const char*) {ctx.endPosArg()}"]
191+
192+
out.append(f"if ({posField} != NULL) " + "{")
193+
out.append(" int error;")
194+
out.append("")
177195
out.append(f" error = {callback}({', '.join(args)});")
178196

179197
# TODO (Vizonex): Deduplicate when indutny updates his side so we can all make our changes accordingly...
180-
out.append(' if (error != 0) {');
181-
out.append(f' {ctx.errorField()} = error;')
182-
out.append(f' {ctx.errorPosField()} = {ctx.endPosArg()};')
183-
out.append(' return error;')
184-
out.append(' }')
185-
out.append('}')
186-
out.append('')
187-
198+
out.append(" if (error != 0) {")
199+
out.append(f" {ctx.errorField()} = error;")
200+
out.append(f" {ctx.errorPosField()} = {ctx.endPosArg()};")
201+
out.append(" return error;")
202+
out.append(" }")
203+
out.append("}")
204+
out.append("")

pyparse/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from .llparse import LLParse
21
from .dot import Dot
2+
from .llparse import LLParse

0 commit comments

Comments
 (0)