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 *
45from .frontend import IFrontendResult
56
67
7- from typing import Optional
8-
98class 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 ("" )
0 commit comments