parser.cpp 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245
  1. struct AstNode;
  2. struct Scope;
  3. struct DeclInfo;
  4. enum ParseFileError {
  5. ParseFile_None,
  6. ParseFile_WrongExtension,
  7. ParseFile_InvalidFile,
  8. ParseFile_EmptyFile,
  9. ParseFile_Permission,
  10. ParseFile_NotFound,
  11. ParseFile_InvalidToken,
  12. ParseFile_Count,
  13. };
  14. typedef Array<AstNode *> AstNodeArray;
  15. struct AstFile {
  16. i32 id;
  17. gbArena arena;
  18. Tokenizer tokenizer;
  19. Array<Token> tokens;
  20. isize curr_token_index;
  21. Token curr_token;
  22. Token prev_token; // previous non-comment
  23. // >= 0: In Expression
  24. // < 0: In Control Clause
  25. // NOTE(bill): Used to prevent type literals in control clauses
  26. isize expr_level;
  27. AstNodeArray decls;
  28. b32 is_global_scope;
  29. AstNode * curr_proc;
  30. isize scope_level;
  31. Scope * scope; // NOTE(bill): Created in checker
  32. DeclInfo * decl_info; // NOTE(bill): Created in checker
  33. // TODO(bill): Error recovery
  34. #define PARSER_MAX_FIX_COUNT 6
  35. isize fix_count;
  36. TokenPos fix_prev_pos;
  37. };
  38. struct ImportedFile {
  39. String path;
  40. String rel_path;
  41. TokenPos pos; // #import
  42. };
  43. struct Parser {
  44. String init_fullpath;
  45. Array<AstFile> files;
  46. Array<ImportedFile> imports;
  47. gbAtomic32 import_index;
  48. Array<String> foreign_libraries;
  49. isize total_token_count;
  50. gbMutex mutex;
  51. };
  52. enum ProcTag : u64 {
  53. ProcTag_bounds_check = GB_BIT(0),
  54. ProcTag_no_bounds_check = GB_BIT(1),
  55. ProcTag_foreign = GB_BIT(10),
  56. ProcTag_link_name = GB_BIT(11),
  57. ProcTag_inline = GB_BIT(12),
  58. ProcTag_no_inline = GB_BIT(13),
  59. ProcTag_dll_import = GB_BIT(14),
  60. ProcTag_dll_export = GB_BIT(15),
  61. ProcTag_stdcall = GB_BIT(16),
  62. ProcTag_fastcall = GB_BIT(17),
  63. // ProcTag_cdecl = GB_BIT(18),
  64. };
  65. enum VarDeclTag {
  66. VarDeclTag_thread_local = GB_BIT(0),
  67. };
  68. enum StmtStateFlag : u32 {
  69. StmtStateFlag_bounds_check = GB_BIT(0),
  70. StmtStateFlag_no_bounds_check = GB_BIT(1),
  71. };
  72. enum CallExprKind {
  73. CallExpr_Prefix, // call(...)
  74. CallExpr_Postfix, // a'call
  75. CallExpr_Infix, // a ''call b
  76. };
  77. AstNodeArray make_ast_node_array(AstFile *f) {
  78. AstNodeArray a;
  79. array_init(&a, gb_arena_allocator(&f->arena));
  80. return a;
  81. }
  82. #define AST_NODE_KINDS \
  83. AST_NODE_KIND(Invalid, "invalid node", struct{}) \
  84. AST_NODE_KIND(BasicLit, "basic literal", Token) \
  85. AST_NODE_KIND(Ident, "identifier", Token) \
  86. AST_NODE_KIND(Ellipsis, "ellipsis", struct { \
  87. Token token; \
  88. AstNode *expr; \
  89. }) \
  90. AST_NODE_KIND(ProcLit, "procedure literal", struct { \
  91. AstNode *type; \
  92. AstNode *body; \
  93. u64 tags; \
  94. }) \
  95. AST_NODE_KIND(CompoundLit, "compound literal", struct { \
  96. AstNode *type; \
  97. AstNodeArray elems; \
  98. Token open, close; \
  99. }) \
  100. AST_NODE_KIND(_ExprBegin, "", struct{}) \
  101. AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \
  102. AST_NODE_KIND(TagExpr, "tag expression", struct { Token token, name; AstNode *expr; }) \
  103. AST_NODE_KIND(RunExpr, "run expression", struct { Token token, name; AstNode *expr; }) \
  104. AST_NODE_KIND(UnaryExpr, "unary expression", struct { Token op; AstNode *expr; }) \
  105. AST_NODE_KIND(BinaryExpr, "binary expression", struct { Token op; AstNode *left, *right; } ) \
  106. AST_NODE_KIND(ParenExpr, "parentheses expression", struct { AstNode *expr; Token open, close; }) \
  107. AST_NODE_KIND(SelectorExpr, "selector expression", struct { Token token; AstNode *expr, *selector; }) \
  108. AST_NODE_KIND(IndexExpr, "index expression", struct { AstNode *expr, *index; Token open, close; }) \
  109. AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \
  110. AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
  111. AST_NODE_KIND(CallExpr, "call expression", struct { \
  112. AstNode *proc; \
  113. AstNodeArray args; \
  114. Token open, close; \
  115. Token ellipsis; \
  116. CallExprKind kind; \
  117. }) \
  118. AST_NODE_KIND(SliceExpr, "slice expression", struct { \
  119. AstNode *expr; \
  120. Token open, close; \
  121. AstNode *low, *high, *max; \
  122. b32 triple_indexed; \
  123. }) \
  124. AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
  125. AST_NODE_KIND(_ExprEnd, "", struct{}) \
  126. AST_NODE_KIND(_StmtBegin, "", struct{}) \
  127. AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \
  128. AST_NODE_KIND(EmptyStmt, "empty statement", struct { Token token; }) \
  129. AST_NODE_KIND(ExprStmt, "expression statement", struct { AstNode *expr; } ) \
  130. AST_NODE_KIND(IncDecStmt, "increment/decrement statement", struct { Token op; AstNode *expr; }) \
  131. AST_NODE_KIND(TagStmt, "tag statement", struct { \
  132. Token token; \
  133. Token name; \
  134. AstNode *stmt; \
  135. }) \
  136. AST_NODE_KIND(AssignStmt, "assign statement", struct { \
  137. Token op; \
  138. AstNodeArray lhs, rhs; \
  139. }) \
  140. AST_NODE_KIND(_ComplexStmtBegin, "", struct{}) \
  141. AST_NODE_KIND(BlockStmt, "block statement", struct { \
  142. AstNodeArray stmts; \
  143. Token open, close; \
  144. }) \
  145. AST_NODE_KIND(IfStmt, "if statement", struct { \
  146. Token token; \
  147. AstNode *init; \
  148. AstNode *cond; \
  149. AstNode *body; \
  150. AstNode *else_stmt; \
  151. }) \
  152. AST_NODE_KIND(ReturnStmt, "return statement", struct { \
  153. Token token; \
  154. AstNodeArray results; \
  155. }) \
  156. AST_NODE_KIND(ForStmt, "for statement", struct { \
  157. Token token; \
  158. AstNode *init, *cond, *post; \
  159. AstNode *body; \
  160. }) \
  161. AST_NODE_KIND(CaseClause, "case clause", struct { \
  162. Token token; \
  163. AstNodeArray list, stmts; \
  164. }) \
  165. AST_NODE_KIND(MatchStmt, "match statement", struct { \
  166. Token token; \
  167. AstNode *init, *tag; \
  168. AstNode *body; \
  169. }) \
  170. AST_NODE_KIND(TypeMatchStmt, "type match statement", struct { \
  171. Token token; \
  172. AstNode *tag, *var; \
  173. AstNode *body; \
  174. }) \
  175. AST_NODE_KIND(DeferStmt, "defer statement", struct { Token token; AstNode *stmt; }) \
  176. AST_NODE_KIND(BranchStmt, "branch statement", struct { Token token; }) \
  177. AST_NODE_KIND(UsingStmt, "using statement", struct { Token token; AstNode *node; }) \
  178. AST_NODE_KIND(AsmOperand, "assembly operand", struct { \
  179. Token string; \
  180. AstNode *operand; \
  181. }) \
  182. AST_NODE_KIND(AsmStmt, "assembly statement", struct { \
  183. Token token; \
  184. b32 is_volatile; \
  185. Token open, close; \
  186. Token code_string; \
  187. AstNode *output_list; \
  188. AstNode *input_list; \
  189. AstNode *clobber_list; \
  190. isize output_count, input_count, clobber_count; \
  191. }) \
  192. AST_NODE_KIND(PushAllocator, "push_allocator statement", struct { \
  193. Token token; \
  194. AstNode *expr; \
  195. AstNode *body; \
  196. }) \
  197. AST_NODE_KIND(PushContext, "push_context statement", struct { \
  198. Token token; \
  199. AstNode *expr; \
  200. AstNode *body; \
  201. }) \
  202. \
  203. AST_NODE_KIND(_ComplexStmtEnd, "", struct{}) \
  204. AST_NODE_KIND(_StmtEnd, "", struct{}) \
  205. AST_NODE_KIND(_DeclBegin, "", struct{}) \
  206. AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
  207. AST_NODE_KIND(VarDecl, "variable declaration", struct { \
  208. u64 tags; \
  209. b32 is_using; \
  210. AstNodeArray names; \
  211. AstNode * type; \
  212. AstNodeArray values; \
  213. AstNode * note; \
  214. }) \
  215. AST_NODE_KIND(ConstDecl, "constant declaration", struct { \
  216. u64 tags; \
  217. AstNodeArray names; \
  218. AstNode * type; \
  219. AstNodeArray values; \
  220. AstNode * note; \
  221. }) \
  222. AST_NODE_KIND(ProcDecl, "procedure declaration", struct { \
  223. AstNode *name; \
  224. AstNode *type; \
  225. AstNode *body; \
  226. u64 tags; \
  227. String foreign_name; \
  228. String link_name; \
  229. AstNode *note; \
  230. }) \
  231. AST_NODE_KIND(TypeDecl, "type declaration", struct { \
  232. Token token; \
  233. AstNode *name, *type; \
  234. AstNode *note; \
  235. }) \
  236. AST_NODE_KIND(ImportDecl, "import declaration", struct { \
  237. Token token, relpath; \
  238. String fullpath; \
  239. Token import_name; \
  240. b32 is_load; \
  241. AstNode *note; \
  242. }) \
  243. AST_NODE_KIND(ForeignLibrary, "foreign library", struct { \
  244. Token token, filepath; \
  245. b32 is_system; \
  246. }) \
  247. AST_NODE_KIND(_DeclEnd, "", struct{}) \
  248. AST_NODE_KIND(_TypeBegin, "", struct{}) \
  249. AST_NODE_KIND(Parameter, "parameter", struct { \
  250. AstNodeArray names; \
  251. AstNode *type; \
  252. b32 is_using; \
  253. }) \
  254. AST_NODE_KIND(ProcType, "procedure type", struct { \
  255. Token token; \
  256. AstNodeArray params; \
  257. AstNodeArray results; \
  258. }) \
  259. AST_NODE_KIND(PointerType, "pointer type", struct { \
  260. Token token; \
  261. AstNode *type; \
  262. }) \
  263. AST_NODE_KIND(MaybeType, "maybe type", struct { \
  264. Token token; \
  265. AstNode *type; \
  266. }) \
  267. AST_NODE_KIND(ArrayType, "array type", struct { \
  268. Token token; \
  269. AstNode *count; \
  270. AstNode *elem; \
  271. }) \
  272. AST_NODE_KIND(VectorType, "vector type", struct { \
  273. Token token; \
  274. AstNode *count; \
  275. AstNode *elem; \
  276. }) \
  277. AST_NODE_KIND(StructType, "struct type", struct { \
  278. Token token; \
  279. AstNodeArray decls; \
  280. isize decl_count; \
  281. b32 is_packed; \
  282. b32 is_ordered; \
  283. }) \
  284. AST_NODE_KIND(UnionType, "union type", struct { \
  285. Token token; \
  286. AstNodeArray decls; \
  287. isize decl_count; \
  288. }) \
  289. AST_NODE_KIND(RawUnionType, "raw union type", struct { \
  290. Token token; \
  291. AstNodeArray decls; \
  292. isize decl_count; \
  293. }) \
  294. AST_NODE_KIND(EnumType, "enum type", struct { \
  295. Token token; \
  296. AstNode *base_type; \
  297. AstNodeArray fields; \
  298. }) \
  299. AST_NODE_KIND(_TypeEnd, "", struct{}) \
  300. AST_NODE_KIND(Count, "", struct{})
  301. enum AstNodeKind {
  302. #define AST_NODE_KIND(_kind_name_, ...) GB_JOIN2(AstNode_, _kind_name_),
  303. AST_NODE_KINDS
  304. #undef AST_NODE_KIND
  305. };
  306. String const ast_node_strings[] = {
  307. #define AST_NODE_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
  308. AST_NODE_KINDS
  309. #undef AST_NODE_KIND
  310. };
  311. #define AST_NODE_KIND(_kind_name_, name, ...) typedef __VA_ARGS__ GB_JOIN2(AstNode, _kind_name_);
  312. AST_NODE_KINDS
  313. #undef AST_NODE_KIND
  314. struct AstNode {
  315. AstNodeKind kind;
  316. // AstNode *prev, *next; // NOTE(bill): allow for Linked list
  317. u32 stmt_state_flags;
  318. union {
  319. #define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_;
  320. AST_NODE_KINDS
  321. #undef AST_NODE_KIND
  322. };
  323. };
  324. #define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_))
  325. #define case_ast_node(n_, Kind_, node_) case GB_JOIN2(AstNode_, Kind_): { ast_node(n_, Kind_, node_);
  326. #define case_end } break;
  327. gb_inline b32 is_ast_node_expr(AstNode *node) {
  328. return gb_is_between(node->kind, AstNode__ExprBegin+1, AstNode__ExprEnd-1);
  329. }
  330. gb_inline b32 is_ast_node_stmt(AstNode *node) {
  331. return gb_is_between(node->kind, AstNode__StmtBegin+1, AstNode__StmtEnd-1);
  332. }
  333. gb_inline b32 is_ast_node_complex_stmt(AstNode *node) {
  334. return gb_is_between(node->kind, AstNode__ComplexStmtBegin+1, AstNode__ComplexStmtEnd-1);
  335. }
  336. gb_inline b32 is_ast_node_decl(AstNode *node) {
  337. return gb_is_between(node->kind, AstNode__DeclBegin+1, AstNode__DeclEnd-1);
  338. }
  339. gb_inline b32 is_ast_node_type(AstNode *node) {
  340. return gb_is_between(node->kind, AstNode__TypeBegin+1, AstNode__TypeEnd-1);
  341. }
  342. Token ast_node_token(AstNode *node) {
  343. switch (node->kind) {
  344. case AstNode_BasicLit:
  345. return node->BasicLit;
  346. case AstNode_Ident:
  347. return node->Ident;
  348. case AstNode_ProcLit:
  349. return ast_node_token(node->ProcLit.type);
  350. case AstNode_CompoundLit:
  351. if (node->CompoundLit.type != NULL) {
  352. return ast_node_token(node->CompoundLit.type);
  353. }
  354. return node->CompoundLit.open;
  355. case AstNode_TagExpr:
  356. return node->TagExpr.token;
  357. case AstNode_RunExpr:
  358. return node->RunExpr.token;
  359. case AstNode_BadExpr:
  360. return node->BadExpr.begin;
  361. case AstNode_UnaryExpr:
  362. return node->UnaryExpr.op;
  363. case AstNode_BinaryExpr:
  364. return ast_node_token(node->BinaryExpr.left);
  365. case AstNode_ParenExpr:
  366. return node->ParenExpr.open;
  367. case AstNode_CallExpr:
  368. return ast_node_token(node->CallExpr.proc);
  369. case AstNode_SelectorExpr:
  370. return ast_node_token(node->SelectorExpr.selector);
  371. case AstNode_IndexExpr:
  372. return node->IndexExpr.open;
  373. case AstNode_SliceExpr:
  374. return node->SliceExpr.open;
  375. case AstNode_Ellipsis:
  376. return node->Ellipsis.token;
  377. case AstNode_FieldValue:
  378. return node->FieldValue.eq;
  379. case AstNode_DerefExpr:
  380. return node->DerefExpr.op;
  381. case AstNode_DemaybeExpr:
  382. return node->DemaybeExpr.op;
  383. case AstNode_BadStmt:
  384. return node->BadStmt.begin;
  385. case AstNode_EmptyStmt:
  386. return node->EmptyStmt.token;
  387. case AstNode_ExprStmt:
  388. return ast_node_token(node->ExprStmt.expr);
  389. case AstNode_TagStmt:
  390. return node->TagStmt.token;
  391. case AstNode_IncDecStmt:
  392. return node->IncDecStmt.op;
  393. case AstNode_AssignStmt:
  394. return node->AssignStmt.op;
  395. case AstNode_BlockStmt:
  396. return node->BlockStmt.open;
  397. case AstNode_IfStmt:
  398. return node->IfStmt.token;
  399. case AstNode_ReturnStmt:
  400. return node->ReturnStmt.token;
  401. case AstNode_ForStmt:
  402. return node->ForStmt.token;
  403. case AstNode_MatchStmt:
  404. return node->MatchStmt.token;
  405. case AstNode_CaseClause:
  406. return node->CaseClause.token;
  407. case AstNode_DeferStmt:
  408. return node->DeferStmt.token;
  409. case AstNode_BranchStmt:
  410. return node->BranchStmt.token;
  411. case AstNode_UsingStmt:
  412. return node->UsingStmt.token;
  413. case AstNode_AsmStmt:
  414. return node->AsmStmt.token;
  415. case AstNode_PushAllocator:
  416. return node->PushAllocator.token;
  417. case AstNode_PushContext:
  418. return node->PushContext.token;
  419. case AstNode_BadDecl:
  420. return node->BadDecl.begin;
  421. case AstNode_VarDecl:
  422. return ast_node_token(node->VarDecl.names[0]);
  423. case AstNode_ConstDecl:
  424. return ast_node_token(node->ConstDecl.names[0]);
  425. case AstNode_ProcDecl:
  426. return node->ProcDecl.name->Ident;
  427. case AstNode_TypeDecl:
  428. return node->TypeDecl.token;
  429. case AstNode_ImportDecl:
  430. return node->ImportDecl.token;
  431. case AstNode_ForeignLibrary:
  432. return node->ForeignLibrary.token;
  433. case AstNode_Parameter: {
  434. if (node->Parameter.names.count > 0) {
  435. return ast_node_token(node->Parameter.names[0]);
  436. } else {
  437. return ast_node_token(node->Parameter.type);
  438. }
  439. }
  440. case AstNode_ProcType:
  441. return node->ProcType.token;
  442. case AstNode_PointerType:
  443. return node->PointerType.token;
  444. case AstNode_MaybeType:
  445. return node->MaybeType.token;
  446. case AstNode_ArrayType:
  447. return node->ArrayType.token;
  448. case AstNode_VectorType:
  449. return node->VectorType.token;
  450. case AstNode_StructType:
  451. return node->StructType.token;
  452. case AstNode_UnionType:
  453. return node->UnionType.token;
  454. case AstNode_RawUnionType:
  455. return node->RawUnionType.token;
  456. case AstNode_EnumType:
  457. return node->EnumType.token;
  458. }
  459. return empty_token;
  460. }
  461. // NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++
  462. AstNode *make_node(AstFile *f, AstNodeKind kind) {
  463. gbArena *arena = &f->arena;
  464. if (gb_arena_size_remaining(arena, GB_DEFAULT_MEMORY_ALIGNMENT) <= gb_size_of(AstNode)) {
  465. // NOTE(bill): If a syntax error is so bad, just quit!
  466. gb_exit(1);
  467. }
  468. AstNode *node = gb_alloc_item(gb_arena_allocator(arena), AstNode);
  469. node->kind = kind;
  470. return node;
  471. }
  472. AstNode *make_bad_expr(AstFile *f, Token begin, Token end) {
  473. AstNode *result = make_node(f, AstNode_BadExpr);
  474. result->BadExpr.begin = begin;
  475. result->BadExpr.end = end;
  476. return result;
  477. }
  478. AstNode *make_tag_expr(AstFile *f, Token token, Token name, AstNode *expr) {
  479. AstNode *result = make_node(f, AstNode_TagExpr);
  480. result->TagExpr.token = token;
  481. result->TagExpr.name = name;
  482. result->TagExpr.expr = expr;
  483. return result;
  484. }
  485. AstNode *make_run_expr(AstFile *f, Token token, Token name, AstNode *expr) {
  486. AstNode *result = make_node(f, AstNode_RunExpr);
  487. result->RunExpr.token = token;
  488. result->RunExpr.name = name;
  489. result->RunExpr.expr = expr;
  490. return result;
  491. }
  492. AstNode *make_tag_stmt(AstFile *f, Token token, Token name, AstNode *stmt) {
  493. AstNode *result = make_node(f, AstNode_TagStmt);
  494. result->TagStmt.token = token;
  495. result->TagStmt.name = name;
  496. result->TagStmt.stmt = stmt;
  497. return result;
  498. }
  499. AstNode *make_unary_expr(AstFile *f, Token op, AstNode *expr) {
  500. AstNode *result = make_node(f, AstNode_UnaryExpr);
  501. result->UnaryExpr.op = op;
  502. result->UnaryExpr.expr = expr;
  503. return result;
  504. }
  505. AstNode *make_binary_expr(AstFile *f, Token op, AstNode *left, AstNode *right) {
  506. AstNode *result = make_node(f, AstNode_BinaryExpr);
  507. if (left == NULL) {
  508. syntax_error(op, "No lhs expression for binary expression `%.*s`", LIT(op.string));
  509. left = make_bad_expr(f, op, op);
  510. }
  511. if (right == NULL) {
  512. syntax_error(op, "No rhs expression for binary expression `%.*s`", LIT(op.string));
  513. right = make_bad_expr(f, op, op);
  514. }
  515. result->BinaryExpr.op = op;
  516. result->BinaryExpr.left = left;
  517. result->BinaryExpr.right = right;
  518. return result;
  519. }
  520. AstNode *make_paren_expr(AstFile *f, AstNode *expr, Token open, Token close) {
  521. AstNode *result = make_node(f, AstNode_ParenExpr);
  522. result->ParenExpr.expr = expr;
  523. result->ParenExpr.open = open;
  524. result->ParenExpr.close = close;
  525. return result;
  526. }
  527. AstNode *make_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, Token close, Token ellipsis) {
  528. AstNode *result = make_node(f, AstNode_CallExpr);
  529. result->CallExpr.proc = proc;
  530. result->CallExpr.args = args;
  531. result->CallExpr.open = open;
  532. result->CallExpr.close = close;
  533. result->CallExpr.ellipsis = ellipsis;
  534. return result;
  535. }
  536. AstNode *make_selector_expr(AstFile *f, Token token, AstNode *expr, AstNode *selector) {
  537. AstNode *result = make_node(f, AstNode_SelectorExpr);
  538. result->SelectorExpr.expr = expr;
  539. result->SelectorExpr.selector = selector;
  540. return result;
  541. }
  542. AstNode *make_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open, Token close) {
  543. AstNode *result = make_node(f, AstNode_IndexExpr);
  544. result->IndexExpr.expr = expr;
  545. result->IndexExpr.index = index;
  546. result->IndexExpr.open = open;
  547. result->IndexExpr.close = close;
  548. return result;
  549. }
  550. AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high, AstNode *max, b32 triple_indexed) {
  551. AstNode *result = make_node(f, AstNode_SliceExpr);
  552. result->SliceExpr.expr = expr;
  553. result->SliceExpr.open = open;
  554. result->SliceExpr.close = close;
  555. result->SliceExpr.low = low;
  556. result->SliceExpr.high = high;
  557. result->SliceExpr.max = max;
  558. result->SliceExpr.triple_indexed = triple_indexed;
  559. return result;
  560. }
  561. AstNode *make_deref_expr(AstFile *f, AstNode *expr, Token op) {
  562. AstNode *result = make_node(f, AstNode_DerefExpr);
  563. result->DerefExpr.expr = expr;
  564. result->DerefExpr.op = op;
  565. return result;
  566. }
  567. AstNode *make_demaybe_expr(AstFile *f, AstNode *expr, Token op) {
  568. AstNode *result = make_node(f, AstNode_DemaybeExpr);
  569. result->DemaybeExpr.expr = expr;
  570. result->DemaybeExpr.op = op;
  571. return result;
  572. }
  573. AstNode *make_basic_lit(AstFile *f, Token basic_lit) {
  574. AstNode *result = make_node(f, AstNode_BasicLit);
  575. result->BasicLit = basic_lit;
  576. return result;
  577. }
  578. AstNode *make_ident(AstFile *f, Token token) {
  579. AstNode *result = make_node(f, AstNode_Ident);
  580. result->Ident = token;
  581. return result;
  582. }
  583. AstNode *make_ellipsis(AstFile *f, Token token, AstNode *expr) {
  584. AstNode *result = make_node(f, AstNode_Ellipsis);
  585. result->Ellipsis.token = token;
  586. result->Ellipsis.expr = expr;
  587. return result;
  588. }
  589. AstNode *make_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags) {
  590. AstNode *result = make_node(f, AstNode_ProcLit);
  591. result->ProcLit.type = type;
  592. result->ProcLit.body = body;
  593. result->ProcLit.tags = tags;
  594. return result;
  595. }
  596. AstNode *make_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq) {
  597. AstNode *result = make_node(f, AstNode_FieldValue);
  598. result->FieldValue.field = field;
  599. result->FieldValue.value = value;
  600. result->FieldValue.eq = eq;
  601. return result;
  602. }
  603. AstNode *make_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) {
  604. AstNode *result = make_node(f, AstNode_CompoundLit);
  605. result->CompoundLit.type = type;
  606. result->CompoundLit.elems = elems;
  607. result->CompoundLit.open = open;
  608. result->CompoundLit.close = close;
  609. return result;
  610. }
  611. AstNode *make_bad_stmt(AstFile *f, Token begin, Token end) {
  612. AstNode *result = make_node(f, AstNode_BadStmt);
  613. result->BadStmt.begin = begin;
  614. result->BadStmt.end = end;
  615. return result;
  616. }
  617. AstNode *make_empty_stmt(AstFile *f, Token token) {
  618. AstNode *result = make_node(f, AstNode_EmptyStmt);
  619. result->EmptyStmt.token = token;
  620. return result;
  621. }
  622. AstNode *make_expr_stmt(AstFile *f, AstNode *expr) {
  623. AstNode *result = make_node(f, AstNode_ExprStmt);
  624. result->ExprStmt.expr = expr;
  625. return result;
  626. }
  627. AstNode *make_inc_dec_stmt(AstFile *f, Token op, AstNode *expr) {
  628. AstNode *result = make_node(f, AstNode_IncDecStmt);
  629. result->IncDecStmt.op = op;
  630. result->IncDecStmt.expr = expr;
  631. return result;
  632. }
  633. AstNode *make_assign_stmt(AstFile *f, Token op, AstNodeArray lhs, AstNodeArray rhs) {
  634. AstNode *result = make_node(f, AstNode_AssignStmt);
  635. result->AssignStmt.op = op;
  636. result->AssignStmt.lhs = lhs;
  637. result->AssignStmt.rhs = rhs;
  638. return result;
  639. }
  640. AstNode *make_block_stmt(AstFile *f, AstNodeArray stmts, Token open, Token close) {
  641. AstNode *result = make_node(f, AstNode_BlockStmt);
  642. result->BlockStmt.stmts = stmts;
  643. result->BlockStmt.open = open;
  644. result->BlockStmt.close = close;
  645. return result;
  646. }
  647. AstNode *make_if_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *body, AstNode *else_stmt) {
  648. AstNode *result = make_node(f, AstNode_IfStmt);
  649. result->IfStmt.token = token;
  650. result->IfStmt.init = init;
  651. result->IfStmt.cond = cond;
  652. result->IfStmt.body = body;
  653. result->IfStmt.else_stmt = else_stmt;
  654. return result;
  655. }
  656. AstNode *make_return_stmt(AstFile *f, Token token, AstNodeArray results) {
  657. AstNode *result = make_node(f, AstNode_ReturnStmt);
  658. result->ReturnStmt.token = token;
  659. result->ReturnStmt.results = results;
  660. return result;
  661. }
  662. AstNode *make_for_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *post, AstNode *body) {
  663. AstNode *result = make_node(f, AstNode_ForStmt);
  664. result->ForStmt.token = token;
  665. result->ForStmt.init = init;
  666. result->ForStmt.cond = cond;
  667. result->ForStmt.post = post;
  668. result->ForStmt.body = body;
  669. return result;
  670. }
  671. AstNode *make_match_stmt(AstFile *f, Token token, AstNode *init, AstNode *tag, AstNode *body) {
  672. AstNode *result = make_node(f, AstNode_MatchStmt);
  673. result->MatchStmt.token = token;
  674. result->MatchStmt.init = init;
  675. result->MatchStmt.tag = tag;
  676. result->MatchStmt.body = body;
  677. return result;
  678. }
  679. AstNode *make_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *var, AstNode *body) {
  680. AstNode *result = make_node(f, AstNode_TypeMatchStmt);
  681. result->TypeMatchStmt.token = token;
  682. result->TypeMatchStmt.tag = tag;
  683. result->TypeMatchStmt.var = var;
  684. result->TypeMatchStmt.body = body;
  685. return result;
  686. }
  687. AstNode *make_case_clause(AstFile *f, Token token, AstNodeArray list, AstNodeArray stmts) {
  688. AstNode *result = make_node(f, AstNode_CaseClause);
  689. result->CaseClause.token = token;
  690. result->CaseClause.list = list;
  691. result->CaseClause.stmts = stmts;
  692. return result;
  693. }
  694. AstNode *make_defer_stmt(AstFile *f, Token token, AstNode *stmt) {
  695. AstNode *result = make_node(f, AstNode_DeferStmt);
  696. result->DeferStmt.token = token;
  697. result->DeferStmt.stmt = stmt;
  698. return result;
  699. }
  700. AstNode *make_branch_stmt(AstFile *f, Token token) {
  701. AstNode *result = make_node(f, AstNode_BranchStmt);
  702. result->BranchStmt.token = token;
  703. return result;
  704. }
  705. AstNode *make_using_stmt(AstFile *f, Token token, AstNode *node) {
  706. AstNode *result = make_node(f, AstNode_UsingStmt);
  707. result->UsingStmt.token = token;
  708. result->UsingStmt.node = node;
  709. return result;
  710. }
  711. AstNode *make_asm_operand(AstFile *f, Token string, AstNode *operand) {
  712. AstNode *result = make_node(f, AstNode_AsmOperand);
  713. result->AsmOperand.string = string;
  714. result->AsmOperand.operand = operand;
  715. return result;
  716. }
  717. AstNode *make_asm_stmt(AstFile *f, Token token, b32 is_volatile, Token open, Token close, Token code_string,
  718. AstNode *output_list, AstNode *input_list, AstNode *clobber_list,
  719. isize output_count, isize input_count, isize clobber_count) {
  720. AstNode *result = make_node(f, AstNode_AsmStmt);
  721. result->AsmStmt.token = token;
  722. result->AsmStmt.is_volatile = is_volatile;
  723. result->AsmStmt.open = open;
  724. result->AsmStmt.close = close;
  725. result->AsmStmt.code_string = code_string;
  726. result->AsmStmt.output_list = output_list;
  727. result->AsmStmt.input_list = input_list;
  728. result->AsmStmt.clobber_list = clobber_list;
  729. result->AsmStmt.output_count = output_count;
  730. result->AsmStmt.input_count = input_count;
  731. result->AsmStmt.clobber_count = clobber_count;
  732. return result;
  733. }
  734. AstNode *make_push_allocator(AstFile *f, Token token, AstNode *expr, AstNode *body) {
  735. AstNode *result = make_node(f, AstNode_PushAllocator);
  736. result->PushAllocator.token = token;
  737. result->PushAllocator.expr = expr;
  738. result->PushAllocator.body = body;
  739. return result;
  740. }
  741. AstNode *make_push_context(AstFile *f, Token token, AstNode *expr, AstNode *body) {
  742. AstNode *result = make_node(f, AstNode_PushContext);
  743. result->PushContext.token = token;
  744. result->PushContext.expr = expr;
  745. result->PushContext.body = body;
  746. return result;
  747. }
  748. AstNode *make_bad_decl(AstFile *f, Token begin, Token end) {
  749. AstNode *result = make_node(f, AstNode_BadDecl);
  750. result->BadDecl.begin = begin;
  751. result->BadDecl.end = end;
  752. return result;
  753. }
  754. AstNode *make_var_decl(AstFile *f, AstNodeArray names, AstNode *type, AstNodeArray values) {
  755. AstNode *result = make_node(f, AstNode_VarDecl);
  756. result->VarDecl.names = names;
  757. result->VarDecl.type = type;
  758. result->VarDecl.values = values;
  759. return result;
  760. }
  761. AstNode *make_const_decl(AstFile *f, AstNodeArray names, AstNode *type, AstNodeArray values) {
  762. AstNode *result = make_node(f, AstNode_ConstDecl);
  763. result->ConstDecl.names = names;
  764. result->ConstDecl.type = type;
  765. result->ConstDecl.values = values;
  766. return result;
  767. }
  768. AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, b32 is_using) {
  769. AstNode *result = make_node(f, AstNode_Parameter);
  770. result->Parameter.names = names;
  771. result->Parameter.type = type;
  772. result->Parameter.is_using = is_using;
  773. return result;
  774. }
  775. AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results) {
  776. AstNode *result = make_node(f, AstNode_ProcType);
  777. result->ProcType.token = token;
  778. result->ProcType.params = params;
  779. result->ProcType.results = results;
  780. return result;
  781. }
  782. AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, u64 tags, String foreign_name, String link_name) {
  783. AstNode *result = make_node(f, AstNode_ProcDecl);
  784. result->ProcDecl.name = name;
  785. result->ProcDecl.type = proc_type;
  786. result->ProcDecl.body = body;
  787. result->ProcDecl.tags = tags;
  788. result->ProcDecl.foreign_name = foreign_name;
  789. result->ProcDecl.link_name = link_name;
  790. return result;
  791. }
  792. AstNode *make_pointer_type(AstFile *f, Token token, AstNode *type) {
  793. AstNode *result = make_node(f, AstNode_PointerType);
  794. result->PointerType.token = token;
  795. result->PointerType.type = type;
  796. return result;
  797. }
  798. AstNode *make_maybe_type(AstFile *f, Token token, AstNode *type) {
  799. AstNode *result = make_node(f, AstNode_MaybeType);
  800. result->MaybeType.token = token;
  801. result->MaybeType.type = type;
  802. return result;
  803. }
  804. AstNode *make_array_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
  805. AstNode *result = make_node(f, AstNode_ArrayType);
  806. result->ArrayType.token = token;
  807. result->ArrayType.count = count;
  808. result->ArrayType.elem = elem;
  809. return result;
  810. }
  811. AstNode *make_vector_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
  812. AstNode *result = make_node(f, AstNode_VectorType);
  813. result->VectorType.token = token;
  814. result->VectorType.count = count;
  815. result->VectorType.elem = elem;
  816. return result;
  817. }
  818. AstNode *make_struct_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count, b32 is_packed, b32 is_ordered) {
  819. AstNode *result = make_node(f, AstNode_StructType);
  820. result->StructType.token = token;
  821. result->StructType.decls = decls;
  822. result->StructType.decl_count = decl_count;
  823. result->StructType.is_packed = is_packed;
  824. result->StructType.is_ordered = is_ordered;
  825. return result;
  826. }
  827. AstNode *make_union_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count) {
  828. AstNode *result = make_node(f, AstNode_UnionType);
  829. result->UnionType.token = token;
  830. result->UnionType.decls = decls;
  831. result->UnionType.decl_count = decl_count;
  832. return result;
  833. }
  834. AstNode *make_raw_union_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count) {
  835. AstNode *result = make_node(f, AstNode_RawUnionType);
  836. result->RawUnionType.token = token;
  837. result->RawUnionType.decls = decls;
  838. result->RawUnionType.decl_count = decl_count;
  839. return result;
  840. }
  841. AstNode *make_enum_type(AstFile *f, Token token, AstNode *base_type, AstNodeArray fields) {
  842. AstNode *result = make_node(f, AstNode_EnumType);
  843. result->EnumType.token = token;
  844. result->EnumType.base_type = base_type;
  845. result->EnumType.fields = fields;
  846. return result;
  847. }
  848. AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNode *type) {
  849. AstNode *result = make_node(f, AstNode_TypeDecl);
  850. result->TypeDecl.token = token;
  851. result->TypeDecl.name = name;
  852. result->TypeDecl.type = type;
  853. return result;
  854. }
  855. AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name, b32 is_load) {
  856. AstNode *result = make_node(f, AstNode_ImportDecl);
  857. result->ImportDecl.token = token;
  858. result->ImportDecl.relpath = relpath;
  859. result->ImportDecl.import_name = import_name;
  860. result->ImportDecl.is_load = is_load;
  861. return result;
  862. }
  863. AstNode *make_foreign_library(AstFile *f, Token token, Token filepath, b32 is_system) {
  864. AstNode *result = make_node(f, AstNode_ForeignLibrary);
  865. result->ForeignLibrary.token = token;
  866. result->ForeignLibrary.filepath = filepath;
  867. result->ForeignLibrary.is_system = is_system;
  868. return result;
  869. }
  870. b32 next_token(AstFile *f) {
  871. if (f->curr_token_index+1 < f->tokens.count) {
  872. if (f->curr_token.kind != Token_Comment) {
  873. f->prev_token = f->curr_token;
  874. }
  875. f->curr_token_index++;
  876. f->curr_token = f->tokens[f->curr_token_index];
  877. if (f->curr_token.kind == Token_Comment) {
  878. return next_token(f);
  879. }
  880. return true;
  881. }
  882. syntax_error(f->curr_token, "Token is EOF");
  883. return false;
  884. }
  885. Token expect_token(AstFile *f, TokenKind kind) {
  886. Token prev = f->curr_token;
  887. if (prev.kind != kind) {
  888. syntax_error(f->curr_token, "Expected `%.*s`, got `%.*s`",
  889. LIT(token_strings[kind]),
  890. LIT(token_strings[prev.kind]));
  891. }
  892. next_token(f);
  893. return prev;
  894. }
  895. Token expect_token_after(AstFile *f, TokenKind kind, char *msg) {
  896. Token prev = f->curr_token;
  897. if (prev.kind != kind) {
  898. syntax_error(f->curr_token, "Expected `%.*s` after %s, got `%.*s`",
  899. LIT(token_strings[kind]),
  900. msg,
  901. LIT(token_strings[prev.kind]));
  902. }
  903. next_token(f);
  904. return prev;
  905. }
  906. Token expect_operator(AstFile *f) {
  907. Token prev = f->curr_token;
  908. if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
  909. syntax_error(f->curr_token, "Expected an operator, got `%.*s`",
  910. LIT(token_strings[prev.kind]));
  911. }
  912. next_token(f);
  913. return prev;
  914. }
  915. Token expect_keyword(AstFile *f) {
  916. Token prev = f->curr_token;
  917. if (!gb_is_between(prev.kind, Token__KeywordBegin+1, Token__KeywordEnd-1)) {
  918. syntax_error(f->curr_token, "Expected a keyword, got `%.*s`",
  919. LIT(token_strings[prev.kind]));
  920. }
  921. next_token(f);
  922. return prev;
  923. }
  924. b32 allow_token(AstFile *f, TokenKind kind) {
  925. Token prev = f->curr_token;
  926. if (prev.kind == kind) {
  927. next_token(f);
  928. return true;
  929. }
  930. return false;
  931. }
  932. b32 is_blank_ident(String str) {
  933. if (str.len == 1) {
  934. return str.text[0] == '_';
  935. }
  936. return false;
  937. }
  938. // NOTE(bill): Go to next statement to prevent numerous error messages popping up
  939. void fix_advance_to_next_stmt(AstFile *f) {
  940. // TODO(bill): fix_advance_to_next_stmt
  941. #if 1
  942. for (;;) {
  943. Token t = f->curr_token;
  944. switch (t.kind) {
  945. case Token_EOF:
  946. case Token_Semicolon:
  947. return;
  948. case Token_if:
  949. case Token_return:
  950. case Token_for:
  951. case Token_match:
  952. case Token_defer:
  953. case Token_asm:
  954. case Token_using:
  955. case Token_break:
  956. case Token_continue:
  957. case Token_fallthrough:
  958. case Token_push_allocator:
  959. case Token_push_context:
  960. case Token_Hash:
  961. {
  962. if (token_pos_are_equal(t.pos, f->fix_prev_pos) &&
  963. f->fix_count < PARSER_MAX_FIX_COUNT) {
  964. f->fix_count++;
  965. return;
  966. }
  967. if (token_pos_cmp(f->fix_prev_pos, t.pos) < 0) {
  968. f->fix_prev_pos = t.pos;
  969. f->fix_count = 0; // NOTE(bill): Reset
  970. return;
  971. }
  972. // NOTE(bill): Reaching here means there is a parsing bug
  973. } break;
  974. }
  975. next_token(f);
  976. }
  977. #endif
  978. }
  979. b32 expect_semicolon_after_stmt(AstFile *f, AstNode *s) {
  980. if (allow_token(f, Token_Semicolon)) {
  981. return true;
  982. }
  983. if (f->curr_token.pos.line != f->prev_token.pos.line) {
  984. return true;
  985. }
  986. switch (f->curr_token.kind) {
  987. case Token_EOF:
  988. case Token_CloseBrace:
  989. return true;
  990. }
  991. syntax_error(f->curr_token,
  992. "Expected `;` after %.*s, got `%.*s`",
  993. LIT(ast_node_strings[s->kind]), LIT(token_strings[f->curr_token.kind]));
  994. fix_advance_to_next_stmt(f);
  995. return false;
  996. }
  997. AstNode * parse_expr(AstFile *f, b32 lhs);
  998. AstNode * parse_proc_type(AstFile *f);
  999. AstNodeArray parse_stmt_list(AstFile *f);
  1000. AstNode * parse_stmt(AstFile *f);
  1001. AstNode * parse_body(AstFile *f);
  1002. AstNode *parse_identifier(AstFile *f) {
  1003. Token token = f->curr_token;
  1004. if (token.kind == Token_Identifier) {
  1005. next_token(f);
  1006. } else {
  1007. token.string = str_lit("_");
  1008. expect_token(f, Token_Identifier);
  1009. }
  1010. return make_ident(f, token);
  1011. }
  1012. AstNode *parse_tag_expr(AstFile *f, AstNode *expression) {
  1013. Token token = expect_token(f, Token_Hash);
  1014. Token name = expect_token(f, Token_Identifier);
  1015. return make_tag_expr(f, token, name, expression);
  1016. }
  1017. AstNode *parse_tag_stmt(AstFile *f, AstNode *statement) {
  1018. Token token = expect_token(f, Token_Hash);
  1019. Token name = expect_token(f, Token_Identifier);
  1020. return make_tag_stmt(f, token, name, statement);
  1021. }
  1022. AstNode *unparen_expr(AstNode *node) {
  1023. for (;;) {
  1024. if (node->kind != AstNode_ParenExpr)
  1025. return node;
  1026. node = node->ParenExpr.expr;
  1027. }
  1028. }
  1029. AstNode *parse_value(AstFile *f);
  1030. AstNodeArray parse_element_list(AstFile *f) {
  1031. AstNodeArray elems = make_ast_node_array(f);
  1032. while (f->curr_token.kind != Token_CloseBrace &&
  1033. f->curr_token.kind != Token_EOF) {
  1034. AstNode *elem = parse_value(f);
  1035. if (f->curr_token.kind == Token_Eq) {
  1036. Token eq = expect_token(f, Token_Eq);
  1037. AstNode *value = parse_value(f);
  1038. elem = make_field_value(f, elem, value, eq);
  1039. }
  1040. array_add(&elems, elem);
  1041. if (f->curr_token.kind != Token_Comma) {
  1042. break;
  1043. }
  1044. next_token(f);
  1045. }
  1046. return elems;
  1047. }
  1048. AstNode *parse_literal_value(AstFile *f, AstNode *type) {
  1049. AstNodeArray elems = {};
  1050. Token open = expect_token(f, Token_OpenBrace);
  1051. f->expr_level++;
  1052. if (f->curr_token.kind != Token_CloseBrace) {
  1053. elems = parse_element_list(f);
  1054. }
  1055. f->expr_level--;
  1056. Token close = expect_token(f, Token_CloseBrace);
  1057. return make_compound_lit(f, type, elems, open, close);
  1058. }
  1059. AstNode *parse_value(AstFile *f) {
  1060. if (f->curr_token.kind == Token_OpenBrace)
  1061. return parse_literal_value(f, NULL);
  1062. AstNode *value = parse_expr(f, false);
  1063. return value;
  1064. }
  1065. AstNode *parse_identifier_or_type(AstFile *f, u32 flags = 0);
  1066. void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) {
  1067. if (*tags & tag) {
  1068. syntax_error(ast_node_token(tag_expr), "Procedure tag already used: %.*s", LIT(tag_name));
  1069. }
  1070. *tags |= tag;
  1071. }
  1072. b32 is_foreign_name_valid(String name) {
  1073. // TODO(bill): is_foreign_name_valid
  1074. if (name.len == 0)
  1075. return false;
  1076. isize offset = 0;
  1077. while (offset < name.len) {
  1078. Rune rune;
  1079. isize remaining = name.len - offset;
  1080. isize width = gb_utf8_decode(name.text+offset, remaining, &rune);
  1081. if (rune == GB_RUNE_INVALID && width == 1) {
  1082. return false;
  1083. } else if (rune == GB_RUNE_BOM && remaining > 0) {
  1084. return false;
  1085. }
  1086. if (offset == 0) {
  1087. switch (rune) {
  1088. case '-':
  1089. case '$':
  1090. case '.':
  1091. case '_':
  1092. break;
  1093. default:
  1094. if (!gb_char_is_alpha(cast(char)rune))
  1095. return false;
  1096. break;
  1097. }
  1098. } else {
  1099. switch (rune) {
  1100. case '-':
  1101. case '$':
  1102. case '.':
  1103. case '_':
  1104. break;
  1105. default:
  1106. if (!gb_char_is_alphanumeric(cast(char)rune)) {
  1107. return false;
  1108. }
  1109. break;
  1110. }
  1111. }
  1112. offset += width;
  1113. }
  1114. return true;
  1115. }
  1116. void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_name) {
  1117. // TODO(bill): Add this to procedure literals too
  1118. GB_ASSERT(foreign_name != NULL);
  1119. GB_ASSERT(link_name != NULL);
  1120. while (f->curr_token.kind == Token_Hash) {
  1121. AstNode *tag_expr = parse_tag_expr(f, NULL);
  1122. ast_node(te, TagExpr, tag_expr);
  1123. String tag_name = te->name.string;
  1124. #define ELSE_IF_ADD_TAG(name) \
  1125. else if (str_eq(tag_name, str_lit(#name))) { \
  1126. check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
  1127. }
  1128. if (str_eq(tag_name, str_lit("foreign"))) {
  1129. check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
  1130. if (f->curr_token.kind == Token_String) {
  1131. *foreign_name = f->curr_token.string;
  1132. // TODO(bill): Check if valid string
  1133. if (!is_foreign_name_valid(*foreign_name)) {
  1134. syntax_error(ast_node_token(tag_expr), "Invalid alternative foreign procedure name: `%.*s`", LIT(*foreign_name));
  1135. }
  1136. next_token(f);
  1137. }
  1138. } else if (str_eq(tag_name, str_lit("link_name"))) {
  1139. check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name);
  1140. if (f->curr_token.kind == Token_String) {
  1141. *link_name = f->curr_token.string;
  1142. // TODO(bill): Check if valid string
  1143. if (!is_foreign_name_valid(*link_name)) {
  1144. syntax_error(ast_node_token(tag_expr), "Invalid alternative link procedure name `%.*s`", LIT(*link_name));
  1145. }
  1146. next_token(f);
  1147. } else {
  1148. expect_token(f, Token_String);
  1149. }
  1150. }
  1151. ELSE_IF_ADD_TAG(bounds_check)
  1152. ELSE_IF_ADD_TAG(no_bounds_check)
  1153. ELSE_IF_ADD_TAG(inline)
  1154. ELSE_IF_ADD_TAG(no_inline)
  1155. ELSE_IF_ADD_TAG(dll_import)
  1156. ELSE_IF_ADD_TAG(dll_export)
  1157. ELSE_IF_ADD_TAG(stdcall)
  1158. ELSE_IF_ADD_TAG(fastcall)
  1159. // ELSE_IF_ADD_TAG(cdecl)
  1160. else {
  1161. syntax_error(ast_node_token(tag_expr), "Unknown procedure tag");
  1162. }
  1163. #undef ELSE_IF_ADD_TAG
  1164. }
  1165. if ((*tags & ProcTag_foreign) && (*tags & ProcTag_link_name)) {
  1166. syntax_error(f->curr_token, "You cannot apply both #foreign and #link_name to a procedure");
  1167. }
  1168. if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) {
  1169. syntax_error(f->curr_token, "You cannot apply both #inline and #no_inline to a procedure");
  1170. }
  1171. if ((*tags & ProcTag_bounds_check) && (*tags & ProcTag_no_bounds_check)) {
  1172. syntax_error(f->curr_token, "You cannot apply both #bounds_check and #no_bounds_check to a procedure");
  1173. }
  1174. if (((*tags & ProcTag_bounds_check) || (*tags & ProcTag_no_bounds_check)) && (*tags & ProcTag_foreign)) {
  1175. syntax_error(f->curr_token, "You cannot apply both #bounds_check or #no_bounds_check to a procedure without a body");
  1176. }
  1177. if ((*tags & ProcTag_stdcall) && (*tags & ProcTag_fastcall)) {
  1178. syntax_error(f->curr_token, "You cannot apply one calling convention to a procedure");
  1179. }
  1180. }
  1181. AstNode *parse_operand(AstFile *f, b32 lhs) {
  1182. AstNode *operand = NULL; // Operand
  1183. switch (f->curr_token.kind) {
  1184. case Token_Identifier:
  1185. operand = parse_identifier(f);
  1186. if (!lhs) {
  1187. // TODO(bill): Handle?
  1188. }
  1189. return operand;
  1190. case Token_Integer:
  1191. case Token_Float:
  1192. case Token_String:
  1193. case Token_Rune:
  1194. operand = make_basic_lit(f, f->curr_token);
  1195. next_token(f);
  1196. return operand;
  1197. case Token_OpenParen: {
  1198. Token open, close;
  1199. // NOTE(bill): Skip the Paren Expression
  1200. open = expect_token(f, Token_OpenParen);
  1201. f->expr_level++;
  1202. operand = parse_expr(f, false);
  1203. f->expr_level--;
  1204. close = expect_token(f, Token_CloseParen);
  1205. return make_paren_expr(f, operand, open, close);
  1206. }
  1207. case Token_Hash: {
  1208. Token token = expect_token(f, Token_Hash);
  1209. Token name = expect_token(f, Token_Identifier);
  1210. if (str_eq(name.string, str_lit("rune"))) {
  1211. if (f->curr_token.kind == Token_String) {
  1212. Token *s = &f->curr_token;
  1213. if (gb_utf8_strnlen(s->string.text, s->string.len) != 1) {
  1214. syntax_error(*s, "Invalid rune literal %.*s", LIT(s->string));
  1215. }
  1216. s->kind = Token_Rune; // NOTE(bill): Change it
  1217. } else {
  1218. expect_token(f, Token_String);
  1219. }
  1220. operand = parse_operand(f, lhs);
  1221. } else if (str_eq(name.string, str_lit("file"))) {
  1222. Token token = name;
  1223. token.kind = Token_String;
  1224. token.string = token.pos.file;
  1225. return make_basic_lit(f, token);
  1226. } else if (str_eq(name.string, str_lit("line"))) {
  1227. Token token = name;
  1228. token.kind = Token_Integer;
  1229. char *str = gb_alloc_array(gb_arena_allocator(&f->arena), char, 20);
  1230. gb_i64_to_str(token.pos.line, str, 10);
  1231. token.string = make_string_c(str);
  1232. return make_basic_lit(f, token);
  1233. } else if (str_eq(name.string, str_lit("run"))) {
  1234. AstNode *expr = parse_expr(f, false);
  1235. operand = make_run_expr(f, token, name, expr);
  1236. if (unparen_expr(expr)->kind != AstNode_CallExpr) {
  1237. error(ast_node_token(expr), "#run can only be applied to procedure calls");
  1238. operand = make_bad_expr(f, token, f->curr_token);
  1239. }
  1240. warning(token, "#run is not yet implemented");
  1241. } else {
  1242. operand = make_tag_expr(f, token, name, parse_expr(f, false));
  1243. }
  1244. return operand;
  1245. }
  1246. // Parse Procedure Type or Literal
  1247. case Token_proc: {
  1248. AstNode *curr_proc = f->curr_proc;
  1249. AstNode *type = parse_proc_type(f);
  1250. f->curr_proc = type;
  1251. u64 tags = 0;
  1252. String foreign_name = {};
  1253. String link_name = {};
  1254. parse_proc_tags(f, &tags, &foreign_name, &link_name);
  1255. if (tags & ProcTag_foreign) {
  1256. syntax_error(f->curr_token, "#foreign cannot be applied to procedure literals");
  1257. }
  1258. if (tags & ProcTag_link_name) {
  1259. syntax_error(f->curr_token, "#link_name cannot be applied to procedure literals");
  1260. }
  1261. if (f->curr_token.kind == Token_OpenBrace) {
  1262. AstNode *body;
  1263. f->expr_level++;
  1264. body = parse_body(f);
  1265. f->expr_level--;
  1266. type = make_proc_lit(f, type, body, tags);
  1267. }
  1268. f->curr_proc = curr_proc;
  1269. return type;
  1270. }
  1271. default: {
  1272. AstNode *type = parse_identifier_or_type(f);
  1273. if (type != NULL) {
  1274. // NOTE(bill): Sanity check as identifiers should be handled already
  1275. GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type Cannot be identifier");
  1276. return type;
  1277. }
  1278. }
  1279. }
  1280. Token begin = f->curr_token;
  1281. syntax_error(begin, "Expected an operand");
  1282. fix_advance_to_next_stmt(f);
  1283. return make_bad_expr(f, begin, f->curr_token);
  1284. }
  1285. b32 is_literal_type(AstNode *node) {
  1286. switch (node->kind) {
  1287. case AstNode_BadExpr:
  1288. case AstNode_Ident:
  1289. case AstNode_SelectorExpr:
  1290. case AstNode_ArrayType:
  1291. case AstNode_VectorType:
  1292. case AstNode_StructType:
  1293. return true;
  1294. }
  1295. return false;
  1296. }
  1297. AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
  1298. AstNodeArray args = make_ast_node_array(f);
  1299. Token open_paren, close_paren;
  1300. Token ellipsis = {};
  1301. f->expr_level++;
  1302. open_paren = expect_token(f, Token_OpenParen);
  1303. while (f->curr_token.kind != Token_CloseParen &&
  1304. f->curr_token.kind != Token_EOF &&
  1305. ellipsis.pos.line == 0) {
  1306. if (f->curr_token.kind == Token_Comma)
  1307. syntax_error(f->curr_token, "Expected an expression not a ,");
  1308. if (f->curr_token.kind == Token_Ellipsis) {
  1309. ellipsis = f->curr_token;
  1310. next_token(f);
  1311. }
  1312. AstNode *arg = parse_expr(f, false);
  1313. array_add(&args, arg);
  1314. if (f->curr_token.kind != Token_Comma) {
  1315. if (f->curr_token.kind == Token_CloseParen)
  1316. break;
  1317. }
  1318. next_token(f);
  1319. }
  1320. f->expr_level--;
  1321. close_paren = expect_token(f, Token_CloseParen);
  1322. return make_call_expr(f, operand, args, open_paren, close_paren, ellipsis);
  1323. }
  1324. AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
  1325. AstNode *operand = parse_operand(f, lhs);
  1326. b32 loop = true;
  1327. while (loop) {
  1328. switch (f->curr_token.kind) {
  1329. case Token_Prime: {
  1330. Token op = expect_token(f, Token_Prime);
  1331. if (lhs) {
  1332. // TODO(bill): Handle this
  1333. }
  1334. AstNode *proc = parse_identifier(f);
  1335. Array<AstNode *> args;
  1336. array_init(&args, gb_arena_allocator(&f->arena), 1);
  1337. array_add(&args, operand);
  1338. operand = make_call_expr(f, proc, args, ast_node_token(operand), op, empty_token);
  1339. } break;
  1340. case Token_OpenParen: {
  1341. if (lhs) {
  1342. // TODO(bill): Handle this shit! Is this even allowed in this language?!
  1343. }
  1344. operand = parse_call_expr(f, operand);
  1345. } break;
  1346. case Token_Period: {
  1347. Token token = f->curr_token;
  1348. next_token(f);
  1349. if (lhs) {
  1350. // TODO(bill): handle this
  1351. }
  1352. switch (f->curr_token.kind) {
  1353. case Token_Identifier:
  1354. operand = make_selector_expr(f, token, operand, parse_identifier(f));
  1355. break;
  1356. default: {
  1357. syntax_error(f->curr_token, "Expected a selector");
  1358. next_token(f);
  1359. operand = make_selector_expr(f, f->curr_token, operand, NULL);
  1360. } break;
  1361. }
  1362. } break;
  1363. case Token_OpenBracket: {
  1364. if (lhs) {
  1365. // TODO(bill): Handle this
  1366. }
  1367. Token open, close;
  1368. AstNode *indices[3] = {};
  1369. f->expr_level++;
  1370. open = expect_token(f, Token_OpenBracket);
  1371. if (f->curr_token.kind != Token_Colon)
  1372. indices[0] = parse_expr(f, false);
  1373. isize colon_count = 0;
  1374. Token colons[2] = {};
  1375. while (f->curr_token.kind == Token_Colon && colon_count < 2) {
  1376. colons[colon_count++] = f->curr_token;
  1377. next_token(f);
  1378. if (f->curr_token.kind != Token_Colon &&
  1379. f->curr_token.kind != Token_CloseBracket &&
  1380. f->curr_token.kind != Token_EOF) {
  1381. indices[colon_count] = parse_expr(f, false);
  1382. }
  1383. }
  1384. f->expr_level--;
  1385. close = expect_token(f, Token_CloseBracket);
  1386. if (colon_count == 0) {
  1387. operand = make_index_expr(f, operand, indices[0], open, close);
  1388. } else {
  1389. b32 triple_indexed = false;
  1390. if (colon_count == 2) {
  1391. triple_indexed = true;
  1392. if (indices[1] == NULL) {
  1393. syntax_error(colons[0], "Second index is required in a triple indexed slice");
  1394. indices[1] = make_bad_expr(f, colons[0], colons[1]);
  1395. }
  1396. if (indices[2] == NULL) {
  1397. syntax_error(colons[1], "Third index is required in a triple indexed slice");
  1398. indices[2] = make_bad_expr(f, colons[1], close);
  1399. }
  1400. }
  1401. operand = make_slice_expr(f, operand, open, close, indices[0], indices[1], indices[2], triple_indexed);
  1402. }
  1403. } break;
  1404. case Token_Pointer: // Deference
  1405. operand = make_deref_expr(f, operand, expect_token(f, Token_Pointer));
  1406. break;
  1407. case Token_Maybe: // Demaybe
  1408. operand = make_demaybe_expr(f, operand, expect_token(f, Token_Maybe));
  1409. break;
  1410. case Token_OpenBrace: {
  1411. if (!lhs && is_literal_type(operand) && f->expr_level >= 0) {
  1412. if (f->curr_token.pos.line == f->prev_token.pos.line) {
  1413. // TODO(bill): This is a hack due to optional semicolons
  1414. // TODO(bill): It's probably much better to solve this by changing
  1415. // the syntax for struct literals and array literals
  1416. operand = parse_literal_value(f, operand);
  1417. } else {
  1418. loop = false;
  1419. }
  1420. } else {
  1421. loop = false;
  1422. }
  1423. } break;
  1424. default:
  1425. loop = false;
  1426. break;
  1427. }
  1428. lhs = false; // NOTE(bill): 'tis not lhs anymore
  1429. }
  1430. return operand;
  1431. }
  1432. AstNode *parse_type(AstFile *f);
  1433. AstNode *parse_unary_expr(AstFile *f, b32 lhs) {
  1434. switch (f->curr_token.kind) {
  1435. case Token_Pointer:
  1436. case Token_Maybe:
  1437. case Token_Add:
  1438. case Token_Sub:
  1439. case Token_Not:
  1440. case Token_Xor: {
  1441. AstNode *operand;
  1442. Token op = f->curr_token;
  1443. next_token(f);
  1444. operand = parse_unary_expr(f, lhs);
  1445. return make_unary_expr(f, op, operand);
  1446. } break;
  1447. }
  1448. return parse_atom_expr(f, lhs);
  1449. }
  1450. // NOTE(bill): result == priority
  1451. i32 token_precedence(Token t) {
  1452. switch (t.kind) {
  1453. case Token_CmpOr:
  1454. return 1;
  1455. case Token_CmpAnd:
  1456. return 2;
  1457. case Token_CmpEq:
  1458. case Token_NotEq:
  1459. case Token_Lt:
  1460. case Token_Gt:
  1461. case Token_LtEq:
  1462. case Token_GtEq:
  1463. return 3;
  1464. case Token_Add:
  1465. case Token_Sub:
  1466. case Token_Or:
  1467. case Token_Xor:
  1468. return 4;
  1469. case Token_Mul:
  1470. case Token_Quo:
  1471. case Token_Mod:
  1472. case Token_And:
  1473. case Token_AndNot:
  1474. case Token_Shl:
  1475. case Token_Shr:
  1476. return 5;
  1477. case Token_DoublePrime:
  1478. return 6;
  1479. case Token_as:
  1480. case Token_transmute:
  1481. case Token_down_cast:
  1482. case Token_union_cast:
  1483. return 7;
  1484. }
  1485. return 0;
  1486. }
  1487. AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) {
  1488. AstNode *expression = parse_unary_expr(f, lhs);
  1489. for (i32 prec = token_precedence(f->curr_token); prec >= prec_in; prec--) {
  1490. for (;;) {
  1491. AstNode *right;
  1492. Token op = f->curr_token;
  1493. i32 op_prec = token_precedence(op);
  1494. if (op_prec != prec)
  1495. break;
  1496. expect_operator(f); // NOTE(bill): error checks too
  1497. if (lhs) {
  1498. // TODO(bill): error checking
  1499. lhs = false;
  1500. }
  1501. switch (op.kind) {
  1502. case Token_DoublePrime: {
  1503. // TODO(bill): Properly define semantic for in-fix and post-fix calls
  1504. AstNode *proc = parse_identifier(f);
  1505. /* if (f->curr_token.kind == Token_OpenParen) {
  1506. AstNode *call = parse_call_expr(f, proc);
  1507. array_add(&call->CallExpr.args, expression);
  1508. for (isize i = gb_array_count(call->CallExpr.args)-1; i > 0; i--) {
  1509. gb_swap(AstNode *, call->CallExpr.args[i], call->CallExpr.args[i-1]);
  1510. }
  1511. expression = call;
  1512. } else */{
  1513. right = parse_binary_expr(f, false, prec+1);
  1514. Array<AstNode *> args = {};
  1515. array_init(&args, gb_arena_allocator(&f->arena), 2);
  1516. array_add(&args, expression);
  1517. array_add(&args, right);
  1518. expression = make_call_expr(f, proc, args, op, ast_node_token(right), empty_token);
  1519. }
  1520. continue;
  1521. } break;
  1522. case Token_as:
  1523. case Token_transmute:
  1524. case Token_down_cast:
  1525. case Token_union_cast:
  1526. right = parse_type(f);
  1527. break;
  1528. default:
  1529. right = parse_binary_expr(f, false, prec+1);
  1530. if (!right) {
  1531. syntax_error(op, "Expected expression on the right hand side of the binary operator");
  1532. }
  1533. break;
  1534. }
  1535. expression = make_binary_expr(f, op, expression, right);
  1536. }
  1537. }
  1538. return expression;
  1539. }
  1540. AstNode *parse_expr(AstFile *f, b32 lhs) {
  1541. return parse_binary_expr(f, lhs, 0+1);
  1542. }
  1543. AstNodeArray parse_expr_list(AstFile *f, b32 lhs) {
  1544. AstNodeArray list = make_ast_node_array(f);
  1545. do {
  1546. AstNode *e = parse_expr(f, lhs);
  1547. array_add(&list, e);
  1548. if (f->curr_token.kind != Token_Comma ||
  1549. f->curr_token.kind == Token_EOF) {
  1550. break;
  1551. }
  1552. next_token(f);
  1553. } while (true);
  1554. return list;
  1555. }
  1556. AstNodeArray parse_lhs_expr_list(AstFile *f) {
  1557. return parse_expr_list(f, true);
  1558. }
  1559. AstNodeArray parse_rhs_expr_list(AstFile *f) {
  1560. return parse_expr_list(f, false);
  1561. }
  1562. AstNode *parse_decl(AstFile *f, AstNodeArray names);
  1563. AstNode *parse_simple_stmt(AstFile *f) {
  1564. isize lhs_count = 0, rhs_count = 0;
  1565. AstNodeArray lhs = parse_lhs_expr_list(f);
  1566. AstNode *statement = NULL;
  1567. Token token = f->curr_token;
  1568. switch (token.kind) {
  1569. case Token_Eq:
  1570. case Token_AddEq:
  1571. case Token_SubEq:
  1572. case Token_MulEq:
  1573. case Token_QuoEq:
  1574. case Token_ModEq:
  1575. case Token_AndEq:
  1576. case Token_OrEq:
  1577. case Token_XorEq:
  1578. case Token_ShlEq:
  1579. case Token_ShrEq:
  1580. case Token_AndNotEq:
  1581. case Token_CmpAndEq:
  1582. case Token_CmpOrEq:
  1583. {
  1584. if (f->curr_proc == NULL) {
  1585. syntax_error(f->curr_token, "You cannot use a simple statement in the file scope");
  1586. return make_bad_stmt(f, f->curr_token, f->curr_token);
  1587. }
  1588. next_token(f);
  1589. AstNodeArray rhs = parse_rhs_expr_list(f);
  1590. if (rhs.count == 0) {
  1591. syntax_error(token, "No right-hand side in assignment statement.");
  1592. return make_bad_stmt(f, token, f->curr_token);
  1593. }
  1594. return make_assign_stmt(f, token, lhs, rhs);
  1595. } break;
  1596. case Token_Colon: // Declare
  1597. return parse_decl(f, lhs);
  1598. }
  1599. if (lhs_count > 1) {
  1600. syntax_error(token, "Expected 1 expression");
  1601. return make_bad_stmt(f, token, f->curr_token);
  1602. }
  1603. token = f->curr_token;
  1604. switch (token.kind) {
  1605. case Token_Increment:
  1606. case Token_Decrement:
  1607. if (f->curr_proc == NULL) {
  1608. syntax_error(f->curr_token, "You cannot use a simple statement in the file scope");
  1609. return make_bad_stmt(f, f->curr_token, f->curr_token);
  1610. }
  1611. statement = make_inc_dec_stmt(f, token, lhs[0]);
  1612. next_token(f);
  1613. return statement;
  1614. }
  1615. return make_expr_stmt(f, lhs[0]);
  1616. }
  1617. AstNode *parse_block_stmt(AstFile *f) {
  1618. if (f->curr_proc == NULL) {
  1619. syntax_error(f->curr_token, "You cannot use a block statement in the file scope");
  1620. return make_bad_stmt(f, f->curr_token, f->curr_token);
  1621. }
  1622. AstNode *block_stmt = parse_body(f);
  1623. return block_stmt;
  1624. }
  1625. AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
  1626. if (statement == NULL)
  1627. return NULL;
  1628. if (statement->kind == AstNode_ExprStmt)
  1629. return statement->ExprStmt.expr;
  1630. syntax_error(f->curr_token, "Expected `%.*s`, found a simple statement.", LIT(kind));
  1631. return make_bad_expr(f, f->curr_token, f->tokens[f->curr_token_index+1]);
  1632. }
  1633. AstNodeArray parse_identfier_list(AstFile *f) {
  1634. AstNodeArray list = make_ast_node_array(f);
  1635. do {
  1636. array_add(&list, parse_identifier(f));
  1637. if (f->curr_token.kind != Token_Comma ||
  1638. f->curr_token.kind == Token_EOF) {
  1639. break;
  1640. }
  1641. next_token(f);
  1642. } while (true);
  1643. return list;
  1644. }
  1645. AstNode *parse_type_attempt(AstFile *f) {
  1646. AstNode *type = parse_identifier_or_type(f);
  1647. if (type != NULL) {
  1648. // TODO(bill): Handle?
  1649. }
  1650. return type;
  1651. }
  1652. AstNode *parse_type(AstFile *f) {
  1653. AstNode *type = parse_type_attempt(f);
  1654. if (type == NULL) {
  1655. Token token = f->curr_token;
  1656. syntax_error(token, "Expected a type");
  1657. next_token(f);
  1658. return make_bad_expr(f, token, f->curr_token);
  1659. }
  1660. return type;
  1661. }
  1662. Token parse_procedure_signature(AstFile *f,
  1663. AstNodeArray *params, AstNodeArray *results);
  1664. AstNode *parse_proc_type(AstFile *f) {
  1665. AstNodeArray params = {};
  1666. AstNodeArray results = {};
  1667. Token proc_token = parse_procedure_signature(f, &params, &results);
  1668. return make_proc_type(f, proc_token, params, results);
  1669. }
  1670. AstNodeArray parse_parameter_list(AstFile *f) {
  1671. AstNodeArray params = make_ast_node_array(f);
  1672. while (f->curr_token.kind == Token_Identifier ||
  1673. f->curr_token.kind == Token_using) {
  1674. b32 is_using = false;
  1675. if (allow_token(f, Token_using)) {
  1676. is_using = true;
  1677. }
  1678. AstNodeArray names = parse_lhs_expr_list(f);
  1679. if (names.count == 0) {
  1680. syntax_error(f->curr_token, "Empty parameter declaration");
  1681. }
  1682. if (names.count > 1 && is_using) {
  1683. syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
  1684. is_using = false;
  1685. }
  1686. expect_token_after(f, Token_Colon, "parameter list");
  1687. AstNode *type = NULL;
  1688. if (f->curr_token.kind == Token_Ellipsis) {
  1689. Token ellipsis = f->curr_token;
  1690. next_token(f);
  1691. type = parse_type_attempt(f);
  1692. if (type == NULL) {
  1693. syntax_error(f->curr_token, "variadic parameter is missing a type after `..`");
  1694. type = make_bad_expr(f, ellipsis, f->curr_token);
  1695. } else {
  1696. if (names.count > 1) {
  1697. syntax_error(f->curr_token, "mutliple variadic parameters, only `..`");
  1698. } else {
  1699. type = make_ellipsis(f, ellipsis, type);
  1700. }
  1701. }
  1702. } else {
  1703. type = parse_type_attempt(f);
  1704. }
  1705. if (type == NULL) {
  1706. syntax_error(f->curr_token, "Expected a type for this parameter declaration");
  1707. }
  1708. array_add(&params, make_parameter(f, names, type, is_using));
  1709. if (f->curr_token.kind != Token_Comma) {
  1710. break;
  1711. }
  1712. next_token(f);
  1713. }
  1714. return params;
  1715. }
  1716. AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allowed) {
  1717. AstNodeArray decls = make_ast_node_array(f);
  1718. isize decl_count = 0;
  1719. while (f->curr_token.kind == Token_Identifier ||
  1720. f->curr_token.kind == Token_using) {
  1721. b32 is_using = false;
  1722. if (allow_token(f, Token_using)) {
  1723. is_using = true;
  1724. }
  1725. AstNodeArray names = parse_lhs_expr_list(f);
  1726. if (names.count == 0) {
  1727. syntax_error(f->curr_token, "Empty field declaration");
  1728. }
  1729. if (!using_allowed && is_using) {
  1730. syntax_error(f->curr_token, "Cannot apply `using` to members of a union");
  1731. is_using = false;
  1732. }
  1733. if (names.count > 1 && is_using) {
  1734. syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
  1735. }
  1736. AstNode *decl = NULL;
  1737. if (f->curr_token.kind == Token_Colon) {
  1738. decl = parse_decl(f, names);
  1739. if (decl->kind == AstNode_ProcDecl) {
  1740. syntax_error(f->curr_token, "Procedure declarations are not allowed within a structure");
  1741. decl = make_bad_decl(f, ast_node_token(names[0]), f->curr_token);
  1742. }
  1743. } else {
  1744. syntax_error(f->curr_token, "Illegal structure field");
  1745. decl = make_bad_decl(f, ast_node_token(names[0]), f->curr_token);
  1746. }
  1747. expect_semicolon_after_stmt(f, decl);
  1748. if (is_ast_node_decl(decl)) {
  1749. array_add(&decls, decl);
  1750. if (decl->kind == AstNode_VarDecl) {
  1751. decl->VarDecl.is_using = is_using && using_allowed;
  1752. if (decl->VarDecl.values.count > 0) {
  1753. syntax_error(f->curr_token, "Default variable assignments within a structure will be ignored (at the moment)");
  1754. }
  1755. } else {
  1756. decl_count += 1;
  1757. }
  1758. }
  1759. }
  1760. if (decl_count_) *decl_count_ = decl_count;
  1761. return decls;
  1762. }
  1763. AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
  1764. switch (f->curr_token.kind) {
  1765. case Token_Identifier: {
  1766. AstNode *e = parse_identifier(f);
  1767. while (f->curr_token.kind == Token_Period) {
  1768. Token token = f->curr_token;
  1769. next_token(f);
  1770. AstNode *sel = parse_identifier(f);
  1771. e = make_selector_expr(f, token, e, sel);
  1772. }
  1773. if (f->curr_token.kind == Token_OpenParen) {
  1774. // HACK NOTE(bill): For type_of_val(expr)
  1775. e = parse_call_expr(f, e);
  1776. }
  1777. return e;
  1778. }
  1779. case Token_Pointer: {
  1780. Token token = expect_token(f, Token_Pointer);
  1781. AstNode *elem = parse_type(f);
  1782. return make_pointer_type(f, token, elem);
  1783. }
  1784. case Token_Maybe: {
  1785. Token token = expect_token(f, Token_Maybe);
  1786. AstNode *elem = parse_type(f);
  1787. return make_maybe_type(f, token, elem);
  1788. }
  1789. case Token_OpenBracket: {
  1790. f->expr_level++;
  1791. Token token = expect_token(f, Token_OpenBracket);
  1792. AstNode *count_expr = NULL;
  1793. if (f->curr_token.kind == Token_Ellipsis) {
  1794. count_expr = make_ellipsis(f, f->curr_token, NULL);
  1795. next_token(f);
  1796. } else if (f->curr_token.kind != Token_CloseBracket) {
  1797. count_expr = parse_expr(f, false);
  1798. }
  1799. expect_token(f, Token_CloseBracket);
  1800. f->expr_level--;
  1801. AstNode *e = make_array_type(f, token, count_expr, parse_type(f));
  1802. return e;
  1803. }
  1804. case Token_OpenBrace: {
  1805. f->expr_level++;
  1806. Token token = expect_token(f, Token_OpenBrace);
  1807. AstNode *count_expr = parse_expr(f, false);
  1808. expect_token(f, Token_CloseBrace);
  1809. f->expr_level--;
  1810. return make_vector_type(f, token, count_expr, parse_type(f));
  1811. }
  1812. case Token_struct: {
  1813. Token token = expect_token(f, Token_struct);
  1814. b32 is_packed = false;
  1815. b32 is_ordered = false;
  1816. while (allow_token(f, Token_Hash)) {
  1817. Token tag = expect_token_after(f, Token_Identifier, "`#`");
  1818. if (str_eq(tag.string, str_lit("packed"))) {
  1819. if (is_packed) {
  1820. syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
  1821. }
  1822. is_packed = true;
  1823. } else if (str_eq(tag.string, str_lit("ordered"))) {
  1824. if (is_ordered) {
  1825. syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
  1826. }
  1827. is_ordered = true;
  1828. } else {
  1829. syntax_error(tag, "Invalid struct tag `#%.*s`", LIT(tag.string));
  1830. }
  1831. }
  1832. if (is_packed && is_ordered) {
  1833. syntax_error(token, "`#ordered` is not needed with `#packed` which implies ordering");
  1834. }
  1835. Token open = expect_token_after(f, Token_OpenBrace, "`struct`");
  1836. isize decl_count = 0;
  1837. AstNodeArray decls = parse_struct_params(f, &decl_count, true);
  1838. Token close = expect_token(f, Token_CloseBrace);
  1839. return make_struct_type(f, token, decls, decl_count, is_packed, is_ordered);
  1840. } break;
  1841. case Token_union: {
  1842. Token token = expect_token(f, Token_union);
  1843. Token open = expect_token_after(f, Token_OpenBrace, "`union`");
  1844. isize decl_count = 0;
  1845. AstNodeArray decls = parse_struct_params(f, &decl_count, false);
  1846. Token close = expect_token(f, Token_CloseBrace);
  1847. return make_union_type(f, token, decls, decl_count);
  1848. }
  1849. case Token_raw_union: {
  1850. Token token = expect_token(f, Token_raw_union);
  1851. Token open = expect_token_after(f, Token_OpenBrace, "`raw_union`");
  1852. isize decl_count = 0;
  1853. AstNodeArray decls = parse_struct_params(f, &decl_count, true);
  1854. Token close = expect_token(f, Token_CloseBrace);
  1855. return make_raw_union_type(f, token, decls, decl_count);
  1856. }
  1857. case Token_enum: {
  1858. Token token = expect_token(f, Token_enum);
  1859. AstNode *base_type = NULL;
  1860. Token open, close;
  1861. if (f->curr_token.kind != Token_OpenBrace) {
  1862. base_type = parse_type(f);
  1863. }
  1864. AstNodeArray fields = make_ast_node_array(f);
  1865. open = expect_token_after(f, Token_OpenBrace, "`enum`");
  1866. while (f->curr_token.kind != Token_CloseBrace &&
  1867. f->curr_token.kind != Token_EOF) {
  1868. AstNode *name = parse_identifier(f);
  1869. AstNode *value = NULL;
  1870. Token eq = empty_token;
  1871. if (f->curr_token.kind == Token_Eq) {
  1872. eq = expect_token(f, Token_Eq);
  1873. value = parse_value(f);
  1874. }
  1875. AstNode *field = make_field_value(f, name, value, eq);
  1876. array_add(&fields, field);
  1877. if (f->curr_token.kind != Token_Comma) {
  1878. break;
  1879. }
  1880. next_token(f);
  1881. }
  1882. close = expect_token(f, Token_CloseBrace);
  1883. return make_enum_type(f, token, base_type, fields);
  1884. }
  1885. case Token_proc:
  1886. return parse_proc_type(f);
  1887. case Token_OpenParen: {
  1888. // NOTE(bill): Skip the paren expression
  1889. AstNode *type;
  1890. Token open, close;
  1891. open = expect_token(f, Token_OpenParen);
  1892. type = parse_type(f);
  1893. close = expect_token(f, Token_CloseParen);
  1894. return type;
  1895. // return make_paren_expr(f, type, open, close);
  1896. }
  1897. // TODO(bill): Why is this even allowed? Is this a parsing error?
  1898. case Token_Colon:
  1899. break;
  1900. case Token_Eq:
  1901. if (f->prev_token.kind == Token_Colon)
  1902. break;
  1903. // fallthrough
  1904. default:
  1905. syntax_error(f->curr_token,
  1906. "Expected a type or identifier after `%.*s`, got `%.*s`", LIT(f->prev_token.string), LIT(f->curr_token.string));
  1907. break;
  1908. }
  1909. return NULL;
  1910. }
  1911. AstNodeArray parse_results(AstFile *f) {
  1912. AstNodeArray results = make_ast_node_array(f);
  1913. if (allow_token(f, Token_ArrowRight)) {
  1914. if (f->curr_token.kind == Token_OpenParen) {
  1915. expect_token(f, Token_OpenParen);
  1916. while (f->curr_token.kind != Token_CloseParen &&
  1917. f->curr_token.kind != Token_EOF) {
  1918. array_add(&results, parse_type(f));
  1919. if (f->curr_token.kind != Token_Comma) {
  1920. break;
  1921. }
  1922. next_token(f);
  1923. }
  1924. expect_token(f, Token_CloseParen);
  1925. return results;
  1926. }
  1927. array_add(&results, parse_type(f));
  1928. return results;
  1929. }
  1930. return results;
  1931. }
  1932. Token parse_procedure_signature(AstFile *f,
  1933. AstNodeArray *params,
  1934. AstNodeArray *results) {
  1935. Token proc_token = expect_token(f, Token_proc);
  1936. expect_token(f, Token_OpenParen);
  1937. *params = parse_parameter_list(f);
  1938. expect_token_after(f, Token_CloseParen, "parameter list");
  1939. *results = parse_results(f);
  1940. return proc_token;
  1941. }
  1942. AstNode *parse_body(AstFile *f) {
  1943. AstNodeArray stmts = {};
  1944. Token open, close;
  1945. open = expect_token(f, Token_OpenBrace);
  1946. stmts = parse_stmt_list(f);
  1947. close = expect_token(f, Token_CloseBrace);
  1948. return make_block_stmt(f, stmts, open, close);
  1949. }
  1950. AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
  1951. AstNodeArray params = {};
  1952. AstNodeArray results = {};
  1953. parse_procedure_signature(f, &params, &results);
  1954. AstNode *proc_type = make_proc_type(f, proc_token, params, results);
  1955. AstNode *body = NULL;
  1956. u64 tags = 0;
  1957. String foreign_name = {};
  1958. String link_name = {};
  1959. parse_proc_tags(f, &tags, &foreign_name, &link_name);
  1960. AstNode *curr_proc = f->curr_proc;
  1961. f->curr_proc = proc_type;
  1962. if (f->curr_token.kind == Token_OpenBrace) {
  1963. if ((tags & ProcTag_foreign) != 0) {
  1964. syntax_error(f->curr_token, "A procedure tagged as `#foreign` cannot have a body");
  1965. }
  1966. body = parse_body(f);
  1967. }
  1968. f->curr_proc = curr_proc;
  1969. return make_proc_decl(f, name, proc_type, body, tags, foreign_name, link_name);
  1970. }
  1971. AstNode *parse_decl(AstFile *f, AstNodeArray names) {
  1972. AstNodeArray values = {};
  1973. AstNode *type = NULL;
  1974. for_array(i, names) {
  1975. AstNode *name = names[i];
  1976. if (name->kind == AstNode_Ident) {
  1977. String n = name->Ident.string;
  1978. // NOTE(bill): Check for reserved identifiers
  1979. if (str_eq(n, str_lit("context"))) {
  1980. syntax_error(ast_node_token(name), "`context` is a reserved identifier");
  1981. break;
  1982. }
  1983. }
  1984. }
  1985. if (allow_token(f, Token_Colon)) {
  1986. if (!allow_token(f, Token_type)) {
  1987. type = parse_identifier_or_type(f);
  1988. }
  1989. } else if (f->curr_token.kind != Token_Eq && f->curr_token.kind != Token_Semicolon) {
  1990. syntax_error(f->curr_token, "Expected type separator `:` or `=`");
  1991. }
  1992. b32 is_mutable = true;
  1993. if (f->curr_token.kind == Token_Eq ||
  1994. f->curr_token.kind == Token_Colon) {
  1995. if (f->curr_token.kind == Token_Colon) {
  1996. is_mutable = false;
  1997. }
  1998. next_token(f);
  1999. if (f->curr_token.kind == Token_type ||
  2000. f->curr_token.kind == Token_struct ||
  2001. f->curr_token.kind == Token_enum ||
  2002. f->curr_token.kind == Token_union ||
  2003. f->curr_token.kind == Token_raw_union) {
  2004. Token token = f->curr_token;
  2005. if (token.kind == Token_type) {
  2006. next_token(f);
  2007. }
  2008. if (names.count != 1) {
  2009. syntax_error(ast_node_token(names[0]), "You can only declare one type at a time");
  2010. return make_bad_decl(f, names[0]->Ident, token);
  2011. }
  2012. if (type != NULL) {
  2013. syntax_error(f->prev_token, "Expected either `type` or nothing between : and :");
  2014. // NOTE(bill): Do not fail though
  2015. }
  2016. return make_type_decl(f, token, names[0], parse_type(f));
  2017. } else if (f->curr_token.kind == Token_proc &&
  2018. is_mutable == false) {
  2019. // NOTE(bill): Procedure declarations
  2020. Token proc_token = f->curr_token;
  2021. AstNode *name = names[0];
  2022. if (names.count != 1) {
  2023. syntax_error(proc_token, "You can only declare one procedure at a time");
  2024. return make_bad_decl(f, name->Ident, proc_token);
  2025. }
  2026. return parse_proc_decl(f, proc_token, name);
  2027. } else {
  2028. values = parse_rhs_expr_list(f);
  2029. if (values.count > names.count) {
  2030. syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
  2031. } else if (values.count < names.count && !is_mutable) {
  2032. syntax_error(f->curr_token, "All constant declarations must be defined");
  2033. } else if (values.count == 0) {
  2034. syntax_error(f->curr_token, "Expected an expression for this declaration");
  2035. }
  2036. }
  2037. }
  2038. if (is_mutable) {
  2039. if (type == NULL && values.count == 0) {
  2040. syntax_error(f->curr_token, "Missing variable type or initialization");
  2041. return make_bad_decl(f, f->curr_token, f->curr_token);
  2042. }
  2043. } else {
  2044. if (type == NULL && values.count == 0 && names.count > 0) {
  2045. syntax_error(f->curr_token, "Missing constant value");
  2046. return make_bad_decl(f, f->curr_token, f->curr_token);
  2047. }
  2048. }
  2049. if (values.data == NULL) {
  2050. values = make_ast_node_array(f);
  2051. }
  2052. if (is_mutable) {
  2053. return make_var_decl(f, names, type, values);
  2054. }
  2055. return make_const_decl(f, names, type, values);
  2056. }
  2057. AstNode *parse_if_stmt(AstFile *f) {
  2058. if (f->curr_proc == NULL) {
  2059. syntax_error(f->curr_token, "You cannot use an if statement in the file scope");
  2060. return make_bad_stmt(f, f->curr_token, f->curr_token);
  2061. }
  2062. Token token = expect_token(f, Token_if);
  2063. AstNode *init = NULL;
  2064. AstNode *cond = NULL;
  2065. AstNode *body = NULL;
  2066. AstNode *else_stmt = NULL;
  2067. isize prev_level = f->expr_level;
  2068. f->expr_level = -1;
  2069. if (allow_token(f, Token_Semicolon)) {
  2070. cond = parse_expr(f, false);
  2071. } else {
  2072. init = parse_simple_stmt(f);
  2073. if (allow_token(f, Token_Semicolon)) {
  2074. cond = parse_expr(f, false);
  2075. } else {
  2076. cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
  2077. init = NULL;
  2078. }
  2079. }
  2080. f->expr_level = prev_level;
  2081. if (cond == NULL) {
  2082. syntax_error(f->curr_token, "Expected condition for if statement");
  2083. }
  2084. body = parse_block_stmt(f);
  2085. if (allow_token(f, Token_else)) {
  2086. switch (f->curr_token.kind) {
  2087. case Token_if:
  2088. else_stmt = parse_if_stmt(f);
  2089. break;
  2090. case Token_OpenBrace:
  2091. else_stmt = parse_block_stmt(f);
  2092. break;
  2093. default:
  2094. syntax_error(f->curr_token, "Expected if statement block statement");
  2095. else_stmt = make_bad_stmt(f, f->curr_token, f->tokens[f->curr_token_index+1]);
  2096. break;
  2097. }
  2098. }
  2099. return make_if_stmt(f, token, init, cond, body, else_stmt);
  2100. }
  2101. AstNode *parse_return_stmt(AstFile *f) {
  2102. if (f->curr_proc == NULL) {
  2103. syntax_error(f->curr_token, "You cannot use a return statement in the file scope");
  2104. return make_bad_stmt(f, f->curr_token, f->curr_token);
  2105. }
  2106. Token token = expect_token(f, Token_return);
  2107. AstNodeArray results = make_ast_node_array(f);
  2108. if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace &&
  2109. f->curr_token.pos.line == token.pos.line) {
  2110. results = parse_rhs_expr_list(f);
  2111. }
  2112. if (f->curr_token.kind != Token_CloseBrace) {
  2113. expect_semicolon_after_stmt(f, results[0]);
  2114. }
  2115. return make_return_stmt(f, token, results);
  2116. }
  2117. AstNode *parse_for_stmt(AstFile *f) {
  2118. if (f->curr_proc == NULL) {
  2119. syntax_error(f->curr_token, "You cannot use a for statement in the file scope");
  2120. return make_bad_stmt(f, f->curr_token, f->curr_token);
  2121. }
  2122. Token token = expect_token(f, Token_for);
  2123. AstNode *init = NULL;
  2124. AstNode *cond = NULL;
  2125. AstNode *end = NULL;
  2126. AstNode *body = NULL;
  2127. if (f->curr_token.kind != Token_OpenBrace) {
  2128. isize prev_level = f->expr_level;
  2129. f->expr_level = -1;
  2130. if (f->curr_token.kind != Token_Semicolon) {
  2131. cond = parse_simple_stmt(f);
  2132. if (is_ast_node_complex_stmt(cond)) {
  2133. syntax_error(f->curr_token,
  2134. "You are not allowed that type of statement in a for statement, it is too complex!");
  2135. }
  2136. }
  2137. if (allow_token(f, Token_Semicolon)) {
  2138. init = cond;
  2139. cond = NULL;
  2140. if (f->curr_token.kind != Token_Semicolon) {
  2141. cond = parse_simple_stmt(f);
  2142. }
  2143. expect_token(f, Token_Semicolon);
  2144. if (f->curr_token.kind != Token_OpenBrace) {
  2145. end = parse_simple_stmt(f);
  2146. }
  2147. }
  2148. f->expr_level = prev_level;
  2149. }
  2150. body = parse_block_stmt(f);
  2151. cond = convert_stmt_to_expr(f, cond, str_lit("boolean expression"));
  2152. return make_for_stmt(f, token, init, cond, end, body);
  2153. }
  2154. AstNode *parse_case_clause(AstFile *f) {
  2155. Token token = f->curr_token;
  2156. AstNodeArray list = make_ast_node_array(f);
  2157. if (allow_token(f, Token_case)) {
  2158. list = parse_rhs_expr_list(f);
  2159. } else {
  2160. expect_token(f, Token_default);
  2161. }
  2162. expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
  2163. // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
  2164. AstNodeArray stmts = parse_stmt_list(f);
  2165. return make_case_clause(f, token, list, stmts);
  2166. }
  2167. AstNode *parse_type_case_clause(AstFile *f) {
  2168. Token token = f->curr_token;
  2169. AstNodeArray clause = make_ast_node_array(f);
  2170. if (allow_token(f, Token_case)) {
  2171. array_add(&clause, parse_type(f));
  2172. } else {
  2173. expect_token(f, Token_default);
  2174. }
  2175. expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
  2176. // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
  2177. AstNodeArray stmts = parse_stmt_list(f);
  2178. return make_case_clause(f, token, clause, stmts);
  2179. }
  2180. AstNode *parse_match_stmt(AstFile *f) {
  2181. if (f->curr_proc == NULL) {
  2182. syntax_error(f->curr_token, "You cannot use a match statement in the file scope");
  2183. return make_bad_stmt(f, f->curr_token, f->curr_token);
  2184. }
  2185. Token token = expect_token(f, Token_match);
  2186. AstNode *init = NULL;
  2187. AstNode *tag = NULL;
  2188. AstNode *body = NULL;
  2189. Token open, close;
  2190. if (allow_token(f, Token_type)) {
  2191. isize prev_level = f->expr_level;
  2192. f->expr_level = -1;
  2193. AstNode *var = parse_identifier(f);
  2194. expect_token(f, Token_Colon);
  2195. tag = parse_simple_stmt(f);
  2196. f->expr_level = prev_level;
  2197. open = expect_token(f, Token_OpenBrace);
  2198. AstNodeArray list = make_ast_node_array(f);
  2199. while (f->curr_token.kind == Token_case ||
  2200. f->curr_token.kind == Token_default) {
  2201. array_add(&list, parse_type_case_clause(f));
  2202. }
  2203. close = expect_token(f, Token_CloseBrace);
  2204. body = make_block_stmt(f, list, open, close);
  2205. tag = convert_stmt_to_expr(f, tag, str_lit("type match expression"));
  2206. return make_type_match_stmt(f, token, tag, var, body);
  2207. } else {
  2208. if (f->curr_token.kind != Token_OpenBrace) {
  2209. isize prev_level = f->expr_level;
  2210. f->expr_level = -1;
  2211. if (f->curr_token.kind != Token_Semicolon) {
  2212. tag = parse_simple_stmt(f);
  2213. }
  2214. if (allow_token(f, Token_Semicolon)) {
  2215. init = tag;
  2216. tag = NULL;
  2217. if (f->curr_token.kind != Token_OpenBrace) {
  2218. tag = parse_simple_stmt(f);
  2219. }
  2220. }
  2221. f->expr_level = prev_level;
  2222. }
  2223. open = expect_token(f, Token_OpenBrace);
  2224. AstNodeArray list = make_ast_node_array(f);
  2225. while (f->curr_token.kind == Token_case ||
  2226. f->curr_token.kind == Token_default) {
  2227. array_add(&list, parse_case_clause(f));
  2228. }
  2229. close = expect_token(f, Token_CloseBrace);
  2230. body = make_block_stmt(f, list, open, close);
  2231. tag = convert_stmt_to_expr(f, tag, str_lit("match expression"));
  2232. return make_match_stmt(f, token, init, tag, body);
  2233. }
  2234. }
  2235. AstNode *parse_defer_stmt(AstFile *f) {
  2236. if (f->curr_proc == NULL) {
  2237. syntax_error(f->curr_token, "You cannot use a defer statement in the file scope");
  2238. return make_bad_stmt(f, f->curr_token, f->curr_token);
  2239. }
  2240. Token token = expect_token(f, Token_defer);
  2241. AstNode *statement = parse_stmt(f);
  2242. switch (statement->kind) {
  2243. case AstNode_EmptyStmt:
  2244. syntax_error(token, "Empty statement after defer (e.g. `;`)");
  2245. break;
  2246. case AstNode_DeferStmt:
  2247. syntax_error(token, "You cannot defer a defer statement");
  2248. break;
  2249. case AstNode_ReturnStmt:
  2250. syntax_error(token, "You cannot a return statement");
  2251. break;
  2252. }
  2253. return make_defer_stmt(f, token, statement);
  2254. }
  2255. AstNode *parse_asm_stmt(AstFile *f) {
  2256. Token token = expect_token(f, Token_asm);
  2257. b32 is_volatile = false;
  2258. if (allow_token(f, Token_volatile)) {
  2259. is_volatile = true;
  2260. }
  2261. Token open, close, code_string;
  2262. open = expect_token(f, Token_OpenBrace);
  2263. code_string = expect_token(f, Token_String);
  2264. AstNode *output_list = NULL;
  2265. AstNode *input_list = NULL;
  2266. AstNode *clobber_list = NULL;
  2267. isize output_count = 0;
  2268. isize input_count = 0;
  2269. isize clobber_count = 0;
  2270. // TODO(bill): Finish asm statement and determine syntax
  2271. // if (f->curr_token.kind != Token_CloseBrace) {
  2272. // expect_token(f, Token_Colon);
  2273. // }
  2274. close = expect_token(f, Token_CloseBrace);
  2275. return make_asm_stmt(f, token, is_volatile, open, close, code_string,
  2276. output_list, input_list, clobber_list,
  2277. output_count, input_count, clobber_count);
  2278. }
  2279. AstNode *parse_stmt(AstFile *f) {
  2280. AstNode *s = NULL;
  2281. Token token = f->curr_token;
  2282. switch (token.kind) {
  2283. // Operands
  2284. case Token_Identifier:
  2285. case Token_Integer:
  2286. case Token_Float:
  2287. case Token_Rune:
  2288. case Token_String:
  2289. case Token_OpenParen:
  2290. case Token_proc:
  2291. // Unary Operators
  2292. case Token_Add:
  2293. case Token_Sub:
  2294. case Token_Xor:
  2295. case Token_Not:
  2296. s = parse_simple_stmt(f);
  2297. expect_semicolon_after_stmt(f, s);
  2298. return s;
  2299. // TODO(bill): other keywords
  2300. case Token_if: return parse_if_stmt(f);
  2301. case Token_return: return parse_return_stmt(f);
  2302. case Token_for: return parse_for_stmt(f);
  2303. case Token_match: return parse_match_stmt(f);
  2304. case Token_defer: return parse_defer_stmt(f);
  2305. case Token_asm: return parse_asm_stmt(f);
  2306. case Token_break:
  2307. case Token_continue:
  2308. case Token_fallthrough:
  2309. next_token(f);
  2310. s = make_branch_stmt(f, token);
  2311. expect_semicolon_after_stmt(f, s);
  2312. return s;
  2313. case Token_using: {
  2314. AstNode *node = NULL;
  2315. next_token(f);
  2316. node = parse_stmt(f);
  2317. b32 valid = false;
  2318. switch (node->kind) {
  2319. case AstNode_ExprStmt: {
  2320. AstNode *e = unparen_expr(node->ExprStmt.expr);
  2321. while (e->kind == AstNode_SelectorExpr) {
  2322. e = unparen_expr(e->SelectorExpr.selector);
  2323. }
  2324. if (e->kind == AstNode_Ident) {
  2325. valid = true;
  2326. }
  2327. } break;
  2328. case AstNode_VarDecl:
  2329. valid = true;
  2330. break;
  2331. }
  2332. if (!valid) {
  2333. syntax_error(token, "Illegal use of `using` statement.");
  2334. return make_bad_stmt(f, token, f->curr_token);
  2335. }
  2336. return make_using_stmt(f, token, node);
  2337. } break;
  2338. case Token_push_allocator: {
  2339. next_token(f);
  2340. isize prev_level = f->expr_level;
  2341. f->expr_level = -1;
  2342. AstNode *expr = parse_expr(f, false);
  2343. f->expr_level = prev_level;
  2344. AstNode *body = parse_block_stmt(f);
  2345. return make_push_allocator(f, token, expr, body);
  2346. } break;
  2347. case Token_push_context: {
  2348. next_token(f);
  2349. isize prev_level = f->expr_level;
  2350. f->expr_level = -1;
  2351. AstNode *expr = parse_expr(f, false);
  2352. f->expr_level = prev_level;
  2353. AstNode *body = parse_block_stmt(f);
  2354. return make_push_context(f, token, expr, body);
  2355. } break;
  2356. case Token_Hash: {
  2357. s = parse_tag_stmt(f, NULL);
  2358. String tag = s->TagStmt.name.string;
  2359. if (str_eq(tag, str_lit("shared_global_scope"))) {
  2360. if (f->curr_proc == NULL) {
  2361. f->is_global_scope = true;
  2362. return make_empty_stmt(f, f->curr_token);
  2363. }
  2364. syntax_error(token, "You cannot use #shared_global_scope within a procedure. This must be done at the file scope");
  2365. return make_bad_decl(f, token, f->curr_token);
  2366. } else if (str_eq(tag, str_lit("import"))) {
  2367. // TODO(bill): better error messages
  2368. Token import_name = {};
  2369. Token file_path = expect_token_after(f, Token_String, "#import");
  2370. if (allow_token(f, Token_as)) {
  2371. // NOTE(bill): Custom import name
  2372. if (f->curr_token.kind == Token_Period) {
  2373. import_name = f->curr_token;
  2374. import_name.kind = Token_Identifier;
  2375. next_token(f);
  2376. } else {
  2377. import_name = expect_token_after(f, Token_Identifier, "`as` for import declaration");
  2378. }
  2379. if (str_eq(import_name.string, str_lit("_"))) {
  2380. syntax_error(token, "Illegal import name: `_`");
  2381. return make_bad_decl(f, token, f->curr_token);
  2382. }
  2383. }
  2384. if (f->curr_proc == NULL) {
  2385. return make_import_decl(f, s->TagStmt.token, file_path, import_name, false);
  2386. }
  2387. syntax_error(token, "You cannot use #import within a procedure. This must be done at the file scope");
  2388. return make_bad_decl(f, token, file_path);
  2389. } else if (str_eq(tag, str_lit("load"))) {
  2390. // TODO(bill): better error messages
  2391. Token file_path = expect_token(f, Token_String);
  2392. Token import_name = file_path;
  2393. import_name.string = str_lit(".");
  2394. if (f->curr_proc == NULL) {
  2395. return make_import_decl(f, s->TagStmt.token, file_path, import_name, true);
  2396. }
  2397. syntax_error(token, "You cannot use #load within a procedure. This must be done at the file scope");
  2398. return make_bad_decl(f, token, file_path);
  2399. } else if (str_eq(tag, str_lit("foreign_system_library"))) {
  2400. Token file_path = expect_token(f, Token_String);
  2401. if (f->curr_proc == NULL) {
  2402. return make_foreign_library(f, s->TagStmt.token, file_path, true);
  2403. }
  2404. syntax_error(token, "You cannot use #foreign_system_library within a procedure. This must be done at the file scope");
  2405. return make_bad_decl(f, token, file_path);
  2406. } else if (str_eq(tag, str_lit("foreign_library"))) {
  2407. Token file_path = expect_token(f, Token_String);
  2408. if (f->curr_proc == NULL) {
  2409. return make_foreign_library(f, s->TagStmt.token, file_path, false);
  2410. }
  2411. syntax_error(token, "You cannot use #foreign_library within a procedure. This must be done at the file scope");
  2412. return make_bad_decl(f, token, file_path);
  2413. } else if (str_eq(tag, str_lit("thread_local"))) {
  2414. AstNode *var_decl = parse_simple_stmt(f);
  2415. if (var_decl->kind != AstNode_VarDecl) {
  2416. syntax_error(token, "#thread_local may only be applied to variable declarations");
  2417. return make_bad_decl(f, token, ast_node_token(var_decl));
  2418. }
  2419. if (f->curr_proc != NULL) {
  2420. syntax_error(token, "#thread_local is only allowed at the file scope");
  2421. return make_bad_decl(f, token, ast_node_token(var_decl));
  2422. }
  2423. var_decl->VarDecl.tags |= VarDeclTag_thread_local;
  2424. return var_decl;
  2425. } else if (str_eq(tag, str_lit("bounds_check"))) {
  2426. s = parse_stmt(f);
  2427. s->stmt_state_flags |= StmtStateFlag_bounds_check;
  2428. if ((s->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) {
  2429. syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
  2430. }
  2431. return s;
  2432. } else if (str_eq(tag, str_lit("no_bounds_check"))) {
  2433. s = parse_stmt(f);
  2434. s->stmt_state_flags |= StmtStateFlag_no_bounds_check;
  2435. if ((s->stmt_state_flags & StmtStateFlag_bounds_check) != 0) {
  2436. syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
  2437. }
  2438. return s;
  2439. }
  2440. s->TagStmt.stmt = parse_stmt(f); // TODO(bill): Find out why this doesn't work as an argument
  2441. return s;
  2442. } break;
  2443. case Token_OpenBrace:
  2444. return parse_block_stmt(f);
  2445. case Token_Semicolon:
  2446. s = make_empty_stmt(f, token);
  2447. next_token(f);
  2448. return s;
  2449. }
  2450. syntax_error(token,
  2451. "Expected a statement, got `%.*s`",
  2452. LIT(token_strings[token.kind]));
  2453. fix_advance_to_next_stmt(f);
  2454. return make_bad_stmt(f, token, f->curr_token);
  2455. }
  2456. AstNodeArray parse_stmt_list(AstFile *f) {
  2457. AstNodeArray list = make_ast_node_array(f);
  2458. while (f->curr_token.kind != Token_case &&
  2459. f->curr_token.kind != Token_default &&
  2460. f->curr_token.kind != Token_CloseBrace &&
  2461. f->curr_token.kind != Token_EOF) {
  2462. AstNode *stmt = parse_stmt(f);
  2463. if (stmt && stmt->kind != AstNode_EmptyStmt) {
  2464. array_add(&list, stmt);
  2465. }
  2466. }
  2467. return list;
  2468. }
  2469. ParseFileError init_ast_file(AstFile *f, String fullpath) {
  2470. if (!string_has_extension(fullpath, str_lit("odin"))) {
  2471. return ParseFile_WrongExtension;
  2472. }
  2473. TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
  2474. if (err == TokenizerInit_None) {
  2475. array_init(&f->tokens, heap_allocator());
  2476. {
  2477. PROF_SCOPED("Tokenize file");
  2478. for (;;) {
  2479. Token token = tokenizer_get_token(&f->tokenizer);
  2480. if (token.kind == Token_Invalid) {
  2481. return ParseFile_InvalidToken;
  2482. }
  2483. array_add(&f->tokens, token);
  2484. if (token.kind == Token_EOF) {
  2485. break;
  2486. }
  2487. }
  2488. }
  2489. f->curr_token_index = 0;
  2490. f->prev_token = f->tokens[f->curr_token_index];
  2491. f->curr_token = f->tokens[f->curr_token_index];
  2492. // NOTE(bill): Is this big enough or too small?
  2493. isize arena_size = gb_size_of(AstNode);
  2494. arena_size *= 2*f->tokens.count;
  2495. gb_arena_init_from_allocator(&f->arena, heap_allocator(), arena_size);
  2496. f->curr_proc = NULL;
  2497. return ParseFile_None;
  2498. }
  2499. switch (err) {
  2500. case TokenizerInit_NotExists:
  2501. return ParseFile_NotFound;
  2502. case TokenizerInit_Permission:
  2503. return ParseFile_Permission;
  2504. case TokenizerInit_Empty:
  2505. return ParseFile_EmptyFile;
  2506. }
  2507. return ParseFile_InvalidFile;
  2508. }
  2509. void destroy_ast_file(AstFile *f) {
  2510. gb_arena_free(&f->arena);
  2511. array_free(&f->tokens);
  2512. gb_free(heap_allocator(), f->tokenizer.fullpath.text);
  2513. destroy_tokenizer(&f->tokenizer);
  2514. }
  2515. b32 init_parser(Parser *p) {
  2516. array_init(&p->files, heap_allocator());
  2517. array_init(&p->imports, heap_allocator());
  2518. array_init(&p->foreign_libraries, heap_allocator());
  2519. gb_mutex_init(&p->mutex);
  2520. return true;
  2521. }
  2522. void destroy_parser(Parser *p) {
  2523. // TODO(bill): Fix memory leak
  2524. for_array(i, p->files) {
  2525. destroy_ast_file(&p->files[i]);
  2526. }
  2527. #if 1
  2528. for_array(i, p->imports) {
  2529. // gb_free(heap_allocator(), p->imports[i].text);
  2530. }
  2531. #endif
  2532. array_free(&p->files);
  2533. array_free(&p->imports);
  2534. array_free(&p->foreign_libraries);
  2535. gb_mutex_destroy(&p->mutex);
  2536. }
  2537. // NOTE(bill): Returns true if it's added
  2538. b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
  2539. gb_mutex_lock(&p->mutex);
  2540. for_array(i, p->imports) {
  2541. String import = p->imports[i].path;
  2542. if (str_eq(import, path)) {
  2543. return false;
  2544. }
  2545. }
  2546. ImportedFile item;
  2547. item.path = path;
  2548. item.rel_path = rel_path;
  2549. item.pos = pos;
  2550. array_add(&p->imports, item);
  2551. gb_mutex_unlock(&p->mutex);
  2552. return true;
  2553. }
  2554. String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
  2555. String res = {};
  2556. isize str_len = base_dir.len+path.len;
  2557. u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
  2558. isize i = 0;
  2559. gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
  2560. gb_memmove(str+i, path.text, path.len);
  2561. str[str_len] = '\0';
  2562. res = path_to_fullpath(a, make_string(str, str_len));
  2563. gb_free(heap_allocator(), str);
  2564. return res;
  2565. }
  2566. String get_fullpath_core(gbAllocator a, String path) {
  2567. String module_dir = get_module_dir();
  2568. String res = {};
  2569. char core[] = "core/";
  2570. isize core_len = gb_size_of(core)-1;
  2571. isize str_len = module_dir.len + core_len + path.len;
  2572. u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
  2573. gb_memmove(str, module_dir.text, module_dir.len);
  2574. gb_memmove(str+module_dir.len, core, core_len);
  2575. gb_memmove(str+module_dir.len+core_len, path.text, path.len);
  2576. str[str_len] = '\0';
  2577. res = path_to_fullpath(a, make_string(str, str_len));
  2578. gb_free(heap_allocator(), str);
  2579. return res;
  2580. }
  2581. // NOTE(bill): Returns true if it's added
  2582. b32 try_add_foreign_library_path(Parser *p, String import_file) {
  2583. gb_mutex_lock(&p->mutex);
  2584. for_array(i, p->foreign_libraries) {
  2585. String import = p->foreign_libraries[i];
  2586. if (str_eq(import, import_file)) {
  2587. return false;
  2588. }
  2589. }
  2590. array_add(&p->foreign_libraries, import_file);
  2591. gb_mutex_unlock(&p->mutex);
  2592. return true;
  2593. }
  2594. gb_global Rune illegal_import_runes[] = {
  2595. '"', '\'', '`', ' ', '\t', '\r', '\n', '\v', '\f',
  2596. '\\', // NOTE(bill): Disallow windows style filepaths
  2597. '!', '$', '%', '^', '&', '*', '(', ')', '=', '+',
  2598. '[', ']', '{', '}',
  2599. ';', ':', '#',
  2600. '|', ',', '<', '>', '?',
  2601. };
  2602. b32 is_import_path_valid(String path) {
  2603. if (path.len > 0) {
  2604. u8 *start = path.text;
  2605. u8 *end = path.text + path.len;
  2606. u8 *curr = start;
  2607. Rune r = -1;
  2608. while (curr < end) {
  2609. isize width = 1;
  2610. r = curr[0];
  2611. if (r >= 0x80) {
  2612. width = gb_utf8_decode(curr, end-curr, &r);
  2613. if (r == GB_RUNE_INVALID && width == 1)
  2614. return false;
  2615. else if (r == GB_RUNE_BOM && curr-start > 0)
  2616. return false;
  2617. }
  2618. for (isize i = 0; i < gb_count_of(illegal_import_runes); i++) {
  2619. if (r == illegal_import_runes[i])
  2620. return false;
  2621. }
  2622. curr += width;
  2623. }
  2624. return true;
  2625. }
  2626. return false;
  2627. }
  2628. String get_filepath_extension(String path) {
  2629. isize dot = 0;
  2630. b32 seen_slash = false;
  2631. for (isize i = path.len-1; i >= 0; i--) {
  2632. u8 c = path.text[i];
  2633. if (c == '/' || c == '\\') {
  2634. seen_slash = true;
  2635. }
  2636. if (c == '.') {
  2637. if (seen_slash) {
  2638. return str_lit("");
  2639. }
  2640. dot = i;
  2641. break;
  2642. }
  2643. }
  2644. return make_string(path.text, dot);
  2645. }
  2646. void parse_file(Parser *p, AstFile *f) {
  2647. PROF_PROC();
  2648. String filepath = f->tokenizer.fullpath;
  2649. String base_dir = filepath;
  2650. for (isize i = filepath.len-1; i >= 0; i--) {
  2651. if (base_dir.text[i] == '\\' ||
  2652. base_dir.text[i] == '/') {
  2653. break;
  2654. }
  2655. base_dir.len--;
  2656. }
  2657. f->decls = parse_stmt_list(f);
  2658. for_array(i, f->decls) {
  2659. AstNode *node = f->decls[i];
  2660. if (!is_ast_node_decl(node) &&
  2661. node->kind != AstNode_BadStmt &&
  2662. node->kind != AstNode_EmptyStmt) {
  2663. // NOTE(bill): Sanity check
  2664. syntax_error(ast_node_token(node), "Only declarations are allowed at file scope");
  2665. } else {
  2666. if (node->kind == AstNode_ImportDecl) {
  2667. auto *id = &node->ImportDecl;
  2668. String file_str = id->relpath.string;
  2669. if (!is_import_path_valid(file_str)) {
  2670. if (id->is_load) {
  2671. syntax_error(ast_node_token(node), "Invalid #load path: `%.*s`", LIT(file_str));
  2672. } else {
  2673. syntax_error(ast_node_token(node), "Invalid #import path: `%.*s`", LIT(file_str));
  2674. }
  2675. // NOTE(bill): It's a naughty name
  2676. f->decls[i] = make_bad_decl(f, id->token, id->token);
  2677. continue;
  2678. }
  2679. gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator
  2680. String rel_path = get_fullpath_relative(allocator, base_dir, file_str);
  2681. String import_file = rel_path;
  2682. if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
  2683. String abs_path = get_fullpath_core(allocator, file_str);
  2684. if (gb_file_exists(cast(char *)abs_path.text)) {
  2685. import_file = abs_path;
  2686. }
  2687. }
  2688. id->fullpath = import_file;
  2689. try_add_import_path(p, import_file, file_str, ast_node_token(node).pos);
  2690. } else if (node->kind == AstNode_ForeignLibrary) {
  2691. auto *id = &node->ForeignLibrary;
  2692. String file_str = id->filepath.string;
  2693. if (!is_import_path_valid(file_str)) {
  2694. if (id->is_system) {
  2695. syntax_error(ast_node_token(node), "Invalid `foreign_system_library` path");
  2696. } else {
  2697. syntax_error(ast_node_token(node), "Invalid `foreign_library` path");
  2698. }
  2699. // NOTE(bill): It's a naughty name
  2700. f->decls[i] = make_bad_decl(f, id->token, id->token);
  2701. continue;
  2702. }
  2703. if (!id->is_system) {
  2704. gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator
  2705. String rel_path = get_fullpath_relative(allocator, base_dir, file_str);
  2706. String import_file = rel_path;
  2707. if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
  2708. String abs_path = get_fullpath_core(allocator, file_str);
  2709. if (gb_file_exists(cast(char *)abs_path.text)) {
  2710. import_file = abs_path;
  2711. }
  2712. }
  2713. file_str = import_file;
  2714. }
  2715. try_add_foreign_library_path(p, file_str);
  2716. }
  2717. }
  2718. }
  2719. }
  2720. ParseFileError parse_files(Parser *p, char *init_filename) {
  2721. char *fullpath_str = gb_path_get_full_name(heap_allocator(), init_filename);
  2722. String init_fullpath = make_string_c(fullpath_str);
  2723. TokenPos init_pos = {};
  2724. ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
  2725. array_add(&p->imports, init_imported_file);
  2726. p->init_fullpath = init_fullpath;
  2727. {
  2728. String s = get_fullpath_core(heap_allocator(), str_lit("_preload.odin"));
  2729. ImportedFile runtime_file = {s, s, init_pos};
  2730. array_add(&p->imports, runtime_file);
  2731. }
  2732. {
  2733. String s = get_fullpath_core(heap_allocator(), str_lit("_soft_numbers.odin"));
  2734. ImportedFile runtime_file = {s, s, init_pos};
  2735. array_add(&p->imports, runtime_file);
  2736. }
  2737. for_array(i, p->imports) {
  2738. ImportedFile imported_file = p->imports[i];
  2739. String import_path = imported_file.path;
  2740. String import_rel_path = imported_file.rel_path;
  2741. TokenPos pos = imported_file.pos;
  2742. AstFile file = {};
  2743. ParseFileError err = init_ast_file(&file, import_path);
  2744. if (err != ParseFile_None) {
  2745. if (pos.line != 0) {
  2746. gb_printf_err("%.*s(%td:%td) ", LIT(pos.file), pos.line, pos.column);
  2747. }
  2748. gb_printf_err("Failed to parse file: %.*s\n\t", LIT(import_rel_path));
  2749. switch (err) {
  2750. case ParseFile_WrongExtension:
  2751. gb_printf_err("Invalid file extension: File must have the extension `.odin`");
  2752. break;
  2753. case ParseFile_InvalidFile:
  2754. gb_printf_err("Invalid file");
  2755. break;
  2756. case ParseFile_EmptyFile:
  2757. gb_printf_err("File is empty");
  2758. break;
  2759. case ParseFile_Permission:
  2760. gb_printf_err("File permissions problem");
  2761. break;
  2762. case ParseFile_NotFound:
  2763. gb_printf_err("File cannot be found");
  2764. break;
  2765. case ParseFile_InvalidToken:
  2766. gb_printf_err("Invalid token found in file");
  2767. break;
  2768. }
  2769. gb_printf_err("\n");
  2770. return err;
  2771. }
  2772. parse_file(p, &file);
  2773. {
  2774. gb_mutex_lock(&p->mutex);
  2775. file.id = p->files.count;
  2776. array_add(&p->files, file);
  2777. gb_mutex_unlock(&p->mutex);
  2778. }
  2779. }
  2780. for_array(i, p->files) {
  2781. p->total_token_count += p->files[i].tokens.count;
  2782. }
  2783. return ParseFile_None;
  2784. }