parser.c 109 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886
  1. typedef struct AstNode AstNode;
  2. typedef struct Scope Scope;
  3. typedef struct DeclInfo DeclInfo;
  4. typedef 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. } ParseFileError;
  14. typedef Array(AstNode *) AstNodeArray;
  15. typedef 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. bool 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. } AstFile;
  38. typedef struct ImportedFile {
  39. String path;
  40. String rel_path;
  41. TokenPos pos; // #import
  42. } ImportedFile;
  43. typedef struct Parser {
  44. String init_fullpath;
  45. Array(AstFile) files;
  46. Array(ImportedFile) imports;
  47. gbAtomic32 import_index;
  48. isize total_token_count;
  49. isize total_line_count;
  50. gbMutex mutex;
  51. } Parser;
  52. typedef enum ProcTag {
  53. ProcTag_bounds_check = 1<<0,
  54. ProcTag_no_bounds_check = 1<<1,
  55. ProcTag_foreign = 1<<10,
  56. ProcTag_export = 1<<11,
  57. ProcTag_link_name = 1<<12,
  58. ProcTag_inline = 1<<13,
  59. ProcTag_no_inline = 1<<14,
  60. // ProcTag_dll_import = 1<<15,
  61. // ProcTag_dll_export = 1<<16,
  62. } ProcTag;
  63. typedef enum ProcCallingConvention {
  64. ProcCC_Odin = 0,
  65. ProcCC_C = 1,
  66. ProcCC_Std = 2,
  67. ProcCC_Fast = 3,
  68. ProcCC_Invalid,
  69. } ProcCallingConvention;
  70. typedef enum VarDeclFlag {
  71. VarDeclFlag_using = 1<<0,
  72. VarDeclFlag_immutable = 1<<1,
  73. VarDeclFlag_thread_local = 1<<2,
  74. } VarDeclFlag;
  75. typedef enum StmtStateFlag {
  76. StmtStateFlag_bounds_check = 1<<0,
  77. StmtStateFlag_no_bounds_check = 1<<1,
  78. } StmtStateFlag;
  79. typedef enum FieldFlag {
  80. FieldFlag_ellipsis = 1<<0,
  81. FieldFlag_using = 1<<1,
  82. FieldFlag_no_alias = 1<<2,
  83. FieldFlag_immutable = 1<<3,
  84. FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_immutable,
  85. } FieldListTag;
  86. AstNodeArray make_ast_node_array(AstFile *f) {
  87. AstNodeArray a;
  88. // array_init(&a, gb_arena_allocator(&f->arena));
  89. array_init(&a, heap_allocator());
  90. return a;
  91. }
  92. // NOTE(bill): This massive define is so it is possible to create a discriminated union (and extra debug info)
  93. // for the AstNode. I personally prefer discriminated unions over subtype polymorphism as I can preallocate
  94. // all the nodes and even memcpy in a different kind of node
  95. #define AST_NODE_KINDS \
  96. AST_NODE_KIND(Ident, "identifier", Token) \
  97. AST_NODE_KIND(Implicit, "implicit", Token) \
  98. AST_NODE_KIND(BasicLit, "basic literal", Token) \
  99. AST_NODE_KIND(BasicDirective, "basic directive", struct { \
  100. Token token; \
  101. String name; \
  102. }) \
  103. AST_NODE_KIND(Ellipsis, "ellipsis", struct { \
  104. Token token; \
  105. AstNode *expr; \
  106. }) \
  107. AST_NODE_KIND(ProcLit, "procedure literal", struct { \
  108. AstNode *type; \
  109. AstNode *body; \
  110. u64 tags; \
  111. AstNode *foreign_library; \
  112. String foreign_name; \
  113. String link_name; \
  114. }) \
  115. AST_NODE_KIND(CompoundLit, "compound literal", struct { \
  116. AstNode *type; \
  117. AstNodeArray elems; \
  118. Token open, close; \
  119. }) \
  120. AST_NODE_KIND(Alias, "alias", struct { \
  121. Token token; \
  122. AstNode *expr; \
  123. }) \
  124. AST_NODE_KIND(_ExprBegin, "", i32) \
  125. AST_NODE_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \
  126. AST_NODE_KIND(TagExpr, "tag expression", struct { Token token, name; AstNode *expr; }) \
  127. AST_NODE_KIND(RunExpr, "run expression", struct { Token token, name; AstNode *expr; }) \
  128. AST_NODE_KIND(UnaryExpr, "unary expression", struct { Token op; AstNode *expr; }) \
  129. AST_NODE_KIND(BinaryExpr, "binary expression", struct { Token op; AstNode *left, *right; } ) \
  130. AST_NODE_KIND(ParenExpr, "parentheses expression", struct { AstNode *expr; Token open, close; }) \
  131. AST_NODE_KIND(SelectorExpr, "selector expression", struct { Token token; AstNode *expr, *selector; }) \
  132. AST_NODE_KIND(IndexExpr, "index expression", struct { AstNode *expr, *index; Token open, close; }) \
  133. AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \
  134. AST_NODE_KIND(SliceExpr, "slice expression", struct { \
  135. AstNode *expr; \
  136. Token open, close; \
  137. bool index3; \
  138. AstNode *low, *high, *max; \
  139. }) \
  140. AST_NODE_KIND(CallExpr, "call expression", struct { \
  141. AstNode * proc; \
  142. AstNodeArray args; \
  143. Token open; \
  144. Token close; \
  145. Token ellipsis; \
  146. }) \
  147. AST_NODE_KIND(MacroCallExpr, "macro call expression", struct { \
  148. AstNode * macro; \
  149. Token bang; \
  150. AstNodeArray args; \
  151. Token open; \
  152. Token close; \
  153. }) \
  154. AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
  155. AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
  156. AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
  157. AST_NODE_KIND(IntervalExpr, "interval expression", struct { Token op; AstNode *left, *right; }) \
  158. AST_NODE_KIND(_ExprEnd, "", i32) \
  159. AST_NODE_KIND(_StmtBegin, "", i32) \
  160. AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \
  161. AST_NODE_KIND(EmptyStmt, "empty statement", struct { Token token; }) \
  162. AST_NODE_KIND(ExprStmt, "expression statement", struct { AstNode *expr; } ) \
  163. AST_NODE_KIND(TagStmt, "tag statement", struct { \
  164. Token token; \
  165. Token name; \
  166. AstNode *stmt; \
  167. }) \
  168. AST_NODE_KIND(AssignStmt, "assign statement", struct { \
  169. Token op; \
  170. AstNodeArray lhs, rhs; \
  171. }) \
  172. AST_NODE_KIND(IncDecStmt, "increment decrement statement", struct { \
  173. Token op; \
  174. AstNode *expr; \
  175. }) \
  176. AST_NODE_KIND(_ComplexStmtBegin, "", i32) \
  177. AST_NODE_KIND(BlockStmt, "block statement", struct { \
  178. AstNodeArray stmts; \
  179. Token open, close; \
  180. }) \
  181. AST_NODE_KIND(IfStmt, "if statement", struct { \
  182. Token token; \
  183. AstNode *init; \
  184. AstNode *cond; \
  185. AstNode *body; \
  186. AstNode *else_stmt; \
  187. }) \
  188. AST_NODE_KIND(WhenStmt, "when statement", struct { \
  189. Token token; \
  190. AstNode *cond; \
  191. AstNode *body; \
  192. AstNode *else_stmt; \
  193. }) \
  194. AST_NODE_KIND(ReturnStmt, "return statement", struct { \
  195. Token token; \
  196. AstNodeArray results; \
  197. }) \
  198. AST_NODE_KIND(ForStmt, "for statement", struct { \
  199. Token token; \
  200. AstNode *label; \
  201. AstNode *init; \
  202. AstNode *cond; \
  203. AstNode *post; \
  204. AstNode *body; \
  205. }) \
  206. AST_NODE_KIND(RangeStmt, "range statement", struct { \
  207. Token token; \
  208. AstNode *label; \
  209. AstNode *value; \
  210. AstNode *index; \
  211. Token in_token; \
  212. AstNode *expr; \
  213. AstNode *body; \
  214. }) \
  215. AST_NODE_KIND(CaseClause, "case clause", struct { \
  216. Token token; \
  217. AstNodeArray list; \
  218. AstNodeArray stmts; \
  219. }) \
  220. AST_NODE_KIND(MatchStmt, "match statement", struct { \
  221. Token token; \
  222. AstNode *label; \
  223. AstNode *init; \
  224. AstNode *tag; \
  225. AstNode *body; \
  226. }) \
  227. AST_NODE_KIND(TypeMatchStmt, "type match statement", struct { \
  228. Token token; \
  229. AstNode *label; \
  230. AstNode *tag; \
  231. AstNode *body; \
  232. }) \
  233. AST_NODE_KIND(DeferStmt, "defer statement", struct { Token token; AstNode *stmt; }) \
  234. AST_NODE_KIND(BranchStmt, "branch statement", struct { Token token; AstNode *label; }) \
  235. AST_NODE_KIND(UsingStmt, "using statement", struct { \
  236. Token token; \
  237. AstNodeArray list; \
  238. }) \
  239. AST_NODE_KIND(AsmOperand, "assembly operand", struct { \
  240. Token string; \
  241. AstNode *operand; \
  242. }) \
  243. AST_NODE_KIND(AsmStmt, "assembly statement", struct { \
  244. Token token; \
  245. bool is_volatile; \
  246. Token open, close; \
  247. Token code_string; \
  248. AstNode *output_list; \
  249. AstNode *input_list; \
  250. AstNode *clobber_list; \
  251. isize output_count, input_count, clobber_count; \
  252. }) \
  253. AST_NODE_KIND(PushAllocator, "push_allocator statement", struct { \
  254. Token token; \
  255. AstNode *expr; \
  256. AstNode *body; \
  257. }) \
  258. AST_NODE_KIND(PushContext, "push_context statement", struct { \
  259. Token token; \
  260. AstNode *expr; \
  261. AstNode *body; \
  262. }) \
  263. AST_NODE_KIND(_ComplexStmtEnd, "", i32) \
  264. AST_NODE_KIND(_StmtEnd, "", i32) \
  265. AST_NODE_KIND(_DeclBegin, "", i32) \
  266. AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
  267. AST_NODE_KIND(ValueDecl, "value declaration", struct { \
  268. bool is_var; \
  269. AstNodeArray names; \
  270. AstNode * type; \
  271. AstNodeArray values; \
  272. u32 flags; \
  273. }) \
  274. AST_NODE_KIND(ImportDecl, "import declaration", struct { \
  275. Token token; \
  276. bool is_import; \
  277. Token relpath; \
  278. String fullpath; \
  279. Token import_name; \
  280. AstNode *cond; \
  281. AstNode *note; \
  282. }) \
  283. AST_NODE_KIND(ForeignLibrary, "foreign library", struct { \
  284. Token token, filepath; \
  285. Token library_name; \
  286. String base_dir; \
  287. AstNode *cond; \
  288. bool is_system; \
  289. }) \
  290. AST_NODE_KIND(Label, "label", struct { \
  291. Token token; \
  292. AstNode *name; \
  293. }) \
  294. AST_NODE_KIND(_DeclEnd, "", i32) \
  295. AST_NODE_KIND(Field, "field", struct { \
  296. AstNodeArray names; \
  297. AstNode * type; \
  298. u32 flags; \
  299. }) \
  300. AST_NODE_KIND(FieldList, "field list", struct { \
  301. Token token; \
  302. AstNodeArray list; \
  303. }) \
  304. AST_NODE_KIND(UnionField, "union field", struct { \
  305. AstNode *name; \
  306. AstNode *list; \
  307. }) \
  308. AST_NODE_KIND(_TypeBegin, "", i32) \
  309. AST_NODE_KIND(HelperType, "type", struct { \
  310. Token token; \
  311. AstNode *type; \
  312. }) \
  313. AST_NODE_KIND(ProcType, "procedure type", struct { \
  314. Token token; \
  315. AstNode *params; \
  316. AstNode *results; \
  317. u64 tags; \
  318. ProcCallingConvention calling_convention; \
  319. }) \
  320. AST_NODE_KIND(PointerType, "pointer type", struct { \
  321. Token token; \
  322. AstNode *type; \
  323. }) \
  324. AST_NODE_KIND(ArrayType, "array type", struct { \
  325. Token token; \
  326. AstNode *count; \
  327. AstNode *elem; \
  328. }) \
  329. AST_NODE_KIND(DynamicArrayType, "dynamic array type", struct { \
  330. Token token; \
  331. AstNode *elem; \
  332. }) \
  333. AST_NODE_KIND(VectorType, "vector type", struct { \
  334. Token token; \
  335. AstNode *count; \
  336. AstNode *elem; \
  337. }) \
  338. AST_NODE_KIND(StructType, "struct type", struct { \
  339. Token token; \
  340. AstNodeArray fields; \
  341. isize field_count; \
  342. bool is_packed; \
  343. bool is_ordered; \
  344. AstNode *align; \
  345. }) \
  346. AST_NODE_KIND(UnionType, "union type", struct { \
  347. Token token; \
  348. AstNodeArray fields; \
  349. isize field_count; \
  350. AstNodeArray variants; \
  351. }) \
  352. AST_NODE_KIND(RawUnionType, "raw union type", struct { \
  353. Token token; \
  354. AstNodeArray fields; \
  355. isize field_count; \
  356. }) \
  357. AST_NODE_KIND(EnumType, "enum type", struct { \
  358. Token token; \
  359. AstNode *base_type; \
  360. AstNodeArray fields; /* FieldValue */ \
  361. }) \
  362. AST_NODE_KIND(MapType, "map type", struct { \
  363. Token token; \
  364. AstNode *count; \
  365. AstNode *key; \
  366. AstNode *value; \
  367. }) \
  368. AST_NODE_KIND(_TypeEnd, "", i32)
  369. typedef enum AstNodeKind {
  370. AstNode_Invalid,
  371. #define AST_NODE_KIND(_kind_name_, ...) GB_JOIN2(AstNode_, _kind_name_),
  372. AST_NODE_KINDS
  373. #undef AST_NODE_KIND
  374. AstNode_Count,
  375. } AstNodeKind;
  376. String const ast_node_strings[] = {
  377. {cast(u8 *)"invalid node", gb_size_of("invalid node")},
  378. #define AST_NODE_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
  379. AST_NODE_KINDS
  380. #undef AST_NODE_KIND
  381. };
  382. #define AST_NODE_KIND(_kind_name_, name, ...) typedef __VA_ARGS__ GB_JOIN2(AstNode, _kind_name_);
  383. AST_NODE_KINDS
  384. #undef AST_NODE_KIND
  385. typedef struct AstNode {
  386. AstNodeKind kind;
  387. u32 stmt_state_flags;
  388. union {
  389. #define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_;
  390. AST_NODE_KINDS
  391. #undef AST_NODE_KIND
  392. };
  393. } AstNode;
  394. #define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_))
  395. #define case_ast_node(n_, Kind_, node_) case GB_JOIN2(AstNode_, Kind_): { ast_node(n_, Kind_, node_);
  396. #ifndef case_end
  397. #define case_end } break;
  398. #endif
  399. gb_inline bool is_ast_node_expr(AstNode *node) {
  400. return gb_is_between(node->kind, AstNode__ExprBegin+1, AstNode__ExprEnd-1);
  401. }
  402. gb_inline bool is_ast_node_stmt(AstNode *node) {
  403. return gb_is_between(node->kind, AstNode__StmtBegin+1, AstNode__StmtEnd-1);
  404. }
  405. gb_inline bool is_ast_node_complex_stmt(AstNode *node) {
  406. return gb_is_between(node->kind, AstNode__ComplexStmtBegin+1, AstNode__ComplexStmtEnd-1);
  407. }
  408. gb_inline bool is_ast_node_decl(AstNode *node) {
  409. return gb_is_between(node->kind, AstNode__DeclBegin+1, AstNode__DeclEnd-1);
  410. }
  411. gb_inline bool is_ast_node_type(AstNode *node) {
  412. return gb_is_between(node->kind, AstNode__TypeBegin+1, AstNode__TypeEnd-1);
  413. }
  414. gb_inline bool is_ast_node_when_stmt(AstNode *node) {
  415. return node->kind == AstNode_WhenStmt;
  416. }
  417. Token ast_node_token(AstNode *node) {
  418. switch (node->kind) {
  419. case AstNode_Ident: return node->Ident;
  420. case AstNode_Implicit: return node->Implicit;
  421. case AstNode_BasicLit: return node->BasicLit;
  422. case AstNode_BasicDirective: return node->BasicDirective.token;
  423. case AstNode_ProcLit: return ast_node_token(node->ProcLit.type);
  424. case AstNode_CompoundLit:
  425. if (node->CompoundLit.type != NULL) {
  426. return ast_node_token(node->CompoundLit.type);
  427. }
  428. return node->CompoundLit.open;
  429. case AstNode_Alias: return node->Alias.token;
  430. case AstNode_TagExpr: return node->TagExpr.token;
  431. case AstNode_RunExpr: return node->RunExpr.token;
  432. case AstNode_BadExpr: return node->BadExpr.begin;
  433. case AstNode_UnaryExpr: return node->UnaryExpr.op;
  434. case AstNode_BinaryExpr: return ast_node_token(node->BinaryExpr.left);
  435. case AstNode_ParenExpr: return node->ParenExpr.open;
  436. case AstNode_CallExpr: return ast_node_token(node->CallExpr.proc);
  437. case AstNode_MacroCallExpr: return ast_node_token(node->MacroCallExpr.macro);
  438. case AstNode_SelectorExpr:
  439. if (node->SelectorExpr.selector != NULL) {
  440. return ast_node_token(node->SelectorExpr.selector);
  441. }
  442. return node->SelectorExpr.token;
  443. case AstNode_IndexExpr: return node->IndexExpr.open;
  444. case AstNode_SliceExpr: return node->SliceExpr.open;
  445. case AstNode_Ellipsis: return node->Ellipsis.token;
  446. case AstNode_CastExpr: return node->CastExpr.token;
  447. case AstNode_FieldValue: return node->FieldValue.eq;
  448. case AstNode_DerefExpr: return node->DerefExpr.op;
  449. case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
  450. case AstNode_IntervalExpr: return ast_node_token(node->IntervalExpr.left);
  451. case AstNode_BadStmt: return node->BadStmt.begin;
  452. case AstNode_EmptyStmt: return node->EmptyStmt.token;
  453. case AstNode_ExprStmt: return ast_node_token(node->ExprStmt.expr);
  454. case AstNode_TagStmt: return node->TagStmt.token;
  455. case AstNode_AssignStmt: return node->AssignStmt.op;
  456. case AstNode_IncDecStmt: return ast_node_token(node->IncDecStmt.expr);
  457. case AstNode_BlockStmt: return node->BlockStmt.open;
  458. case AstNode_IfStmt: return node->IfStmt.token;
  459. case AstNode_WhenStmt: return node->WhenStmt.token;
  460. case AstNode_ReturnStmt: return node->ReturnStmt.token;
  461. case AstNode_ForStmt: return node->ForStmt.token;
  462. case AstNode_RangeStmt: return node->RangeStmt.token;
  463. case AstNode_MatchStmt: return node->MatchStmt.token;
  464. case AstNode_CaseClause: return node->CaseClause.token;
  465. case AstNode_DeferStmt: return node->DeferStmt.token;
  466. case AstNode_BranchStmt: return node->BranchStmt.token;
  467. case AstNode_UsingStmt: return node->UsingStmt.token;
  468. case AstNode_AsmStmt: return node->AsmStmt.token;
  469. case AstNode_PushAllocator: return node->PushAllocator.token;
  470. case AstNode_PushContext: return node->PushContext.token;
  471. case AstNode_BadDecl: return node->BadDecl.begin;
  472. case AstNode_ValueDecl: return ast_node_token(node->ValueDecl.names.e[0]);
  473. case AstNode_ImportDecl: return node->ImportDecl.token;
  474. case AstNode_ForeignLibrary: return node->ForeignLibrary.token;
  475. case AstNode_Label: return node->Label.token;
  476. case AstNode_Field:
  477. if (node->Field.names.count > 0) {
  478. return ast_node_token(node->Field.names.e[0]);
  479. }
  480. return ast_node_token(node->Field.type);
  481. case AstNode_FieldList:
  482. return node->FieldList.token;
  483. case AstNode_UnionField:
  484. return ast_node_token(node->UnionField.name);
  485. case AstNode_HelperType: return node->HelperType.token;
  486. case AstNode_ProcType: return node->ProcType.token;
  487. case AstNode_PointerType: return node->PointerType.token;
  488. case AstNode_ArrayType: return node->ArrayType.token;
  489. case AstNode_DynamicArrayType: return node->DynamicArrayType.token;
  490. case AstNode_VectorType: return node->VectorType.token;
  491. case AstNode_StructType: return node->StructType.token;
  492. case AstNode_UnionType: return node->UnionType.token;
  493. case AstNode_RawUnionType: return node->RawUnionType.token;
  494. case AstNode_EnumType: return node->EnumType.token;
  495. case AstNode_MapType: return node->MapType.token;
  496. }
  497. return empty_token;
  498. }
  499. void error_node(AstNode *node, char *fmt, ...) {
  500. va_list va;
  501. va_start(va, fmt);
  502. error_va(ast_node_token(node), fmt, va);
  503. va_end(va);
  504. }
  505. void warning_node(AstNode *node, char *fmt, ...) {
  506. va_list va;
  507. va_start(va, fmt);
  508. warning_va(ast_node_token(node), fmt, va);
  509. va_end(va);
  510. }
  511. void syntax_error_node(AstNode *node, char *fmt, ...) {
  512. va_list va;
  513. va_start(va, fmt);
  514. syntax_error_va(ast_node_token(node), fmt, va);
  515. va_end(va);
  516. }
  517. bool ast_node_expect(AstNode *node, AstNodeKind kind) {
  518. if (node->kind != kind) {
  519. error_node(node, "Expected %.*s, got %.*s", LIT(ast_node_strings[node->kind]));
  520. return false;
  521. }
  522. return true;
  523. }
  524. // NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++
  525. AstNode *make_ast_node(AstFile *f, AstNodeKind kind) {
  526. gbArena *arena = &f->arena;
  527. if (gb_arena_size_remaining(arena, GB_DEFAULT_MEMORY_ALIGNMENT) <= gb_size_of(AstNode)) {
  528. // NOTE(bill): If a syntax error is so bad, just quit!
  529. gb_exit(1);
  530. }
  531. AstNode *node = gb_alloc_item(gb_arena_allocator(arena), AstNode);
  532. node->kind = kind;
  533. return node;
  534. }
  535. AstNode *ast_bad_expr(AstFile *f, Token begin, Token end) {
  536. AstNode *result = make_ast_node(f, AstNode_BadExpr);
  537. result->BadExpr.begin = begin;
  538. result->BadExpr.end = end;
  539. return result;
  540. }
  541. AstNode *ast_tag_expr(AstFile *f, Token token, Token name, AstNode *expr) {
  542. AstNode *result = make_ast_node(f, AstNode_TagExpr);
  543. result->TagExpr.token = token;
  544. result->TagExpr.name = name;
  545. result->TagExpr.expr = expr;
  546. return result;
  547. }
  548. AstNode *ast_run_expr(AstFile *f, Token token, Token name, AstNode *expr) {
  549. AstNode *result = make_ast_node(f, AstNode_RunExpr);
  550. result->RunExpr.token = token;
  551. result->RunExpr.name = name;
  552. result->RunExpr.expr = expr;
  553. return result;
  554. }
  555. AstNode *ast_tag_stmt(AstFile *f, Token token, Token name, AstNode *stmt) {
  556. AstNode *result = make_ast_node(f, AstNode_TagStmt);
  557. result->TagStmt.token = token;
  558. result->TagStmt.name = name;
  559. result->TagStmt.stmt = stmt;
  560. return result;
  561. }
  562. AstNode *ast_unary_expr(AstFile *f, Token op, AstNode *expr) {
  563. AstNode *result = make_ast_node(f, AstNode_UnaryExpr);
  564. result->UnaryExpr.op = op;
  565. result->UnaryExpr.expr = expr;
  566. return result;
  567. }
  568. AstNode *ast_binary_expr(AstFile *f, Token op, AstNode *left, AstNode *right) {
  569. AstNode *result = make_ast_node(f, AstNode_BinaryExpr);
  570. if (left == NULL) {
  571. syntax_error(op, "No lhs expression for binary expression `%.*s`", LIT(op.string));
  572. left = ast_bad_expr(f, op, op);
  573. }
  574. if (right == NULL) {
  575. syntax_error(op, "No rhs expression for binary expression `%.*s`", LIT(op.string));
  576. right = ast_bad_expr(f, op, op);
  577. }
  578. result->BinaryExpr.op = op;
  579. result->BinaryExpr.left = left;
  580. result->BinaryExpr.right = right;
  581. return result;
  582. }
  583. AstNode *ast_paren_expr(AstFile *f, AstNode *expr, Token open, Token close) {
  584. AstNode *result = make_ast_node(f, AstNode_ParenExpr);
  585. result->ParenExpr.expr = expr;
  586. result->ParenExpr.open = open;
  587. result->ParenExpr.close = close;
  588. return result;
  589. }
  590. AstNode *ast_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, Token close, Token ellipsis) {
  591. AstNode *result = make_ast_node(f, AstNode_CallExpr);
  592. result->CallExpr.proc = proc;
  593. result->CallExpr.args = args;
  594. result->CallExpr.open = open;
  595. result->CallExpr.close = close;
  596. result->CallExpr.ellipsis = ellipsis;
  597. return result;
  598. }
  599. AstNode *ast_macro_call_expr(AstFile *f, AstNode *macro, Token bang, AstNodeArray args, Token open, Token close) {
  600. AstNode *result = make_ast_node(f, AstNode_MacroCallExpr);
  601. result->MacroCallExpr.macro = macro;
  602. result->MacroCallExpr.bang = bang;
  603. result->MacroCallExpr.args = args;
  604. result->MacroCallExpr.open = open;
  605. result->MacroCallExpr.close = close;
  606. return result;
  607. }
  608. AstNode *ast_selector_expr(AstFile *f, Token token, AstNode *expr, AstNode *selector) {
  609. AstNode *result = make_ast_node(f, AstNode_SelectorExpr);
  610. result->SelectorExpr.expr = expr;
  611. result->SelectorExpr.selector = selector;
  612. return result;
  613. }
  614. AstNode *ast_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open, Token close) {
  615. AstNode *result = make_ast_node(f, AstNode_IndexExpr);
  616. result->IndexExpr.expr = expr;
  617. result->IndexExpr.index = index;
  618. result->IndexExpr.open = open;
  619. result->IndexExpr.close = close;
  620. return result;
  621. }
  622. AstNode *ast_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, bool index3, AstNode *low, AstNode *high, AstNode *max) {
  623. AstNode *result = make_ast_node(f, AstNode_SliceExpr);
  624. result->SliceExpr.expr = expr;
  625. result->SliceExpr.open = open;
  626. result->SliceExpr.close = close;
  627. result->SliceExpr.index3 = index3;
  628. result->SliceExpr.low = low;
  629. result->SliceExpr.high = high;
  630. result->SliceExpr.max = max;
  631. return result;
  632. }
  633. AstNode *ast_deref_expr(AstFile *f, AstNode *expr, Token op) {
  634. AstNode *result = make_ast_node(f, AstNode_DerefExpr);
  635. result->DerefExpr.expr = expr;
  636. result->DerefExpr.op = op;
  637. return result;
  638. }
  639. AstNode *ast_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right) {
  640. AstNode *result = make_ast_node(f, AstNode_IntervalExpr);
  641. result->IntervalExpr.op = op;
  642. result->IntervalExpr.left = left;
  643. result->IntervalExpr.right = right;
  644. return result;
  645. }
  646. AstNode *ast_ident(AstFile *f, Token token) {
  647. AstNode *result = make_ast_node(f, AstNode_Ident);
  648. result->Ident = token;
  649. return result;
  650. }
  651. AstNode *ast_implicit(AstFile *f, Token token) {
  652. AstNode *result = make_ast_node(f, AstNode_Implicit);
  653. result->Implicit = token;
  654. return result;
  655. }
  656. AstNode *ast_basic_lit(AstFile *f, Token basic_lit) {
  657. AstNode *result = make_ast_node(f, AstNode_BasicLit);
  658. result->BasicLit = basic_lit;
  659. return result;
  660. }
  661. AstNode *ast_basic_directive(AstFile *f, Token token, String name) {
  662. AstNode *result = make_ast_node(f, AstNode_BasicDirective);
  663. result->BasicDirective.token = token;
  664. result->BasicDirective.name = name;
  665. return result;
  666. }
  667. AstNode *ast_ellipsis(AstFile *f, Token token, AstNode *expr) {
  668. AstNode *result = make_ast_node(f, AstNode_Ellipsis);
  669. result->Ellipsis.token = token;
  670. result->Ellipsis.expr = expr;
  671. return result;
  672. }
  673. AstNode *ast_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, AstNode *foreign_library, String foreign_name, String link_name) {
  674. AstNode *result = make_ast_node(f, AstNode_ProcLit);
  675. result->ProcLit.type = type;
  676. result->ProcLit.body = body;
  677. result->ProcLit.tags = tags;
  678. result->ProcLit.foreign_library = foreign_library;
  679. result->ProcLit.foreign_name = foreign_name;
  680. result->ProcLit.link_name = link_name;
  681. return result;
  682. }
  683. AstNode *ast_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq) {
  684. AstNode *result = make_ast_node(f, AstNode_FieldValue);
  685. result->FieldValue.field = field;
  686. result->FieldValue.value = value;
  687. result->FieldValue.eq = eq;
  688. return result;
  689. }
  690. AstNode *ast_cast_expr(AstFile *f, Token token, AstNode *type, AstNode *expr, Token open, Token close) {
  691. AstNode *result = make_ast_node(f, AstNode_CastExpr);
  692. result->CastExpr.token = token;
  693. result->CastExpr.type = type;
  694. result->CastExpr.expr = expr;
  695. result->CastExpr.open = open;
  696. result->CastExpr.close = close;
  697. return result;
  698. }
  699. AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) {
  700. AstNode *result = make_ast_node(f, AstNode_CompoundLit);
  701. result->CompoundLit.type = type;
  702. result->CompoundLit.elems = elems;
  703. result->CompoundLit.open = open;
  704. result->CompoundLit.close = close;
  705. return result;
  706. }
  707. AstNode *ast_alias(AstFile *f, Token token, AstNode *expr) {
  708. AstNode *result = make_ast_node(f, AstNode_Alias);
  709. result->Alias.token = token;
  710. result->Alias.expr = expr;
  711. return result;
  712. }
  713. AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
  714. AstNode *result = make_ast_node(f, AstNode_TernaryExpr);
  715. result->TernaryExpr.cond = cond;
  716. result->TernaryExpr.x = x;
  717. result->TernaryExpr.y = y;
  718. return result;
  719. }
  720. AstNode *ast_bad_stmt(AstFile *f, Token begin, Token end) {
  721. AstNode *result = make_ast_node(f, AstNode_BadStmt);
  722. result->BadStmt.begin = begin;
  723. result->BadStmt.end = end;
  724. return result;
  725. }
  726. AstNode *ast_empty_stmt(AstFile *f, Token token) {
  727. AstNode *result = make_ast_node(f, AstNode_EmptyStmt);
  728. result->EmptyStmt.token = token;
  729. return result;
  730. }
  731. AstNode *ast_expr_stmt(AstFile *f, AstNode *expr) {
  732. AstNode *result = make_ast_node(f, AstNode_ExprStmt);
  733. result->ExprStmt.expr = expr;
  734. return result;
  735. }
  736. AstNode *ast_assign_stmt(AstFile *f, Token op, AstNodeArray lhs, AstNodeArray rhs) {
  737. AstNode *result = make_ast_node(f, AstNode_AssignStmt);
  738. result->AssignStmt.op = op;
  739. result->AssignStmt.lhs = lhs;
  740. result->AssignStmt.rhs = rhs;
  741. return result;
  742. }
  743. AstNode *ast_inc_dec_stmt(AstFile *f, Token op, AstNode *expr) {
  744. AstNode *result = make_ast_node(f, AstNode_IncDecStmt);
  745. result->IncDecStmt.op = op;
  746. result->IncDecStmt.expr = expr;
  747. return result;
  748. }
  749. AstNode *ast_block_stmt(AstFile *f, AstNodeArray stmts, Token open, Token close) {
  750. AstNode *result = make_ast_node(f, AstNode_BlockStmt);
  751. result->BlockStmt.stmts = stmts;
  752. result->BlockStmt.open = open;
  753. result->BlockStmt.close = close;
  754. return result;
  755. }
  756. AstNode *ast_if_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *body, AstNode *else_stmt) {
  757. AstNode *result = make_ast_node(f, AstNode_IfStmt);
  758. result->IfStmt.token = token;
  759. result->IfStmt.init = init;
  760. result->IfStmt.cond = cond;
  761. result->IfStmt.body = body;
  762. result->IfStmt.else_stmt = else_stmt;
  763. return result;
  764. }
  765. AstNode *ast_when_stmt(AstFile *f, Token token, AstNode *cond, AstNode *body, AstNode *else_stmt) {
  766. AstNode *result = make_ast_node(f, AstNode_WhenStmt);
  767. result->WhenStmt.token = token;
  768. result->WhenStmt.cond = cond;
  769. result->WhenStmt.body = body;
  770. result->WhenStmt.else_stmt = else_stmt;
  771. return result;
  772. }
  773. AstNode *ast_return_stmt(AstFile *f, Token token, AstNodeArray results) {
  774. AstNode *result = make_ast_node(f, AstNode_ReturnStmt);
  775. result->ReturnStmt.token = token;
  776. result->ReturnStmt.results = results;
  777. return result;
  778. }
  779. AstNode *ast_for_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *post, AstNode *body) {
  780. AstNode *result = make_ast_node(f, AstNode_ForStmt);
  781. result->ForStmt.token = token;
  782. result->ForStmt.init = init;
  783. result->ForStmt.cond = cond;
  784. result->ForStmt.post = post;
  785. result->ForStmt.body = body;
  786. return result;
  787. }
  788. AstNode *ast_range_stmt(AstFile *f, Token token, AstNode *value, AstNode *index, Token in_token, AstNode *expr, AstNode *body) {
  789. AstNode *result = make_ast_node(f, AstNode_RangeStmt);
  790. result->RangeStmt.token = token;
  791. result->RangeStmt.value = value;
  792. result->RangeStmt.index = index;
  793. result->RangeStmt.in_token = in_token;
  794. result->RangeStmt.expr = expr;
  795. result->RangeStmt.body = body;
  796. return result;
  797. }
  798. AstNode *ast_match_stmt(AstFile *f, Token token, AstNode *init, AstNode *tag, AstNode *body) {
  799. AstNode *result = make_ast_node(f, AstNode_MatchStmt);
  800. result->MatchStmt.token = token;
  801. result->MatchStmt.init = init;
  802. result->MatchStmt.tag = tag;
  803. result->MatchStmt.body = body;
  804. return result;
  805. }
  806. AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *body) {
  807. AstNode *result = make_ast_node(f, AstNode_TypeMatchStmt);
  808. result->TypeMatchStmt.token = token;
  809. result->TypeMatchStmt.tag = tag;
  810. result->TypeMatchStmt.body = body;
  811. return result;
  812. }
  813. AstNode *ast_case_clause(AstFile *f, Token token, AstNodeArray list, AstNodeArray stmts) {
  814. AstNode *result = make_ast_node(f, AstNode_CaseClause);
  815. result->CaseClause.token = token;
  816. result->CaseClause.list = list;
  817. result->CaseClause.stmts = stmts;
  818. return result;
  819. }
  820. AstNode *ast_defer_stmt(AstFile *f, Token token, AstNode *stmt) {
  821. AstNode *result = make_ast_node(f, AstNode_DeferStmt);
  822. result->DeferStmt.token = token;
  823. result->DeferStmt.stmt = stmt;
  824. return result;
  825. }
  826. AstNode *ast_branch_stmt(AstFile *f, Token token, AstNode *label) {
  827. AstNode *result = make_ast_node(f, AstNode_BranchStmt);
  828. result->BranchStmt.token = token;
  829. result->BranchStmt.label = label;
  830. return result;
  831. }
  832. AstNode *ast_using_stmt(AstFile *f, Token token, AstNodeArray list) {
  833. AstNode *result = make_ast_node(f, AstNode_UsingStmt);
  834. result->UsingStmt.token = token;
  835. result->UsingStmt.list = list;
  836. return result;
  837. }
  838. AstNode *ast_asm_operand(AstFile *f, Token string, AstNode *operand) {
  839. AstNode *result = make_ast_node(f, AstNode_AsmOperand);
  840. result->AsmOperand.string = string;
  841. result->AsmOperand.operand = operand;
  842. return result;
  843. }
  844. AstNode *ast_asm_stmt(AstFile *f, Token token, bool is_volatile, Token open, Token close, Token code_string,
  845. AstNode *output_list, AstNode *input_list, AstNode *clobber_list,
  846. isize output_count, isize input_count, isize clobber_count) {
  847. AstNode *result = make_ast_node(f, AstNode_AsmStmt);
  848. result->AsmStmt.token = token;
  849. result->AsmStmt.is_volatile = is_volatile;
  850. result->AsmStmt.open = open;
  851. result->AsmStmt.close = close;
  852. result->AsmStmt.code_string = code_string;
  853. result->AsmStmt.output_list = output_list;
  854. result->AsmStmt.input_list = input_list;
  855. result->AsmStmt.clobber_list = clobber_list;
  856. result->AsmStmt.output_count = output_count;
  857. result->AsmStmt.input_count = input_count;
  858. result->AsmStmt.clobber_count = clobber_count;
  859. return result;
  860. }
  861. AstNode *ast_push_allocator(AstFile *f, Token token, AstNode *expr, AstNode *body) {
  862. AstNode *result = make_ast_node(f, AstNode_PushAllocator);
  863. result->PushAllocator.token = token;
  864. result->PushAllocator.expr = expr;
  865. result->PushAllocator.body = body;
  866. return result;
  867. }
  868. AstNode *ast_push_context(AstFile *f, Token token, AstNode *expr, AstNode *body) {
  869. AstNode *result = make_ast_node(f, AstNode_PushContext);
  870. result->PushContext.token = token;
  871. result->PushContext.expr = expr;
  872. result->PushContext.body = body;
  873. return result;
  874. }
  875. AstNode *ast_bad_decl(AstFile *f, Token begin, Token end) {
  876. AstNode *result = make_ast_node(f, AstNode_BadDecl);
  877. result->BadDecl.begin = begin;
  878. result->BadDecl.end = end;
  879. return result;
  880. }
  881. AstNode *ast_field(AstFile *f, AstNodeArray names, AstNode *type, u32 flags) {
  882. AstNode *result = make_ast_node(f, AstNode_Field);
  883. result->Field.names = names;
  884. result->Field.type = type;
  885. result->Field.flags = flags;
  886. return result;
  887. }
  888. AstNode *ast_field_list(AstFile *f, Token token, AstNodeArray list) {
  889. AstNode *result = make_ast_node(f, AstNode_FieldList);
  890. result->FieldList.token = token;
  891. result->FieldList.list = list;
  892. return result;
  893. }
  894. AstNode *ast_union_field(AstFile *f, AstNode *name, AstNode *list) {
  895. AstNode *result = make_ast_node(f, AstNode_UnionField);
  896. result->UnionField.name = name;
  897. result->UnionField.list = list;
  898. return result;
  899. }
  900. AstNode *ast_helper_type(AstFile *f, Token token, AstNode *type) {
  901. AstNode *result = make_ast_node(f, AstNode_HelperType);
  902. result->HelperType.token = token;
  903. result->HelperType.type = type;
  904. return result;
  905. }
  906. AstNode *ast_proc_type(AstFile *f, Token token, AstNode *params, AstNode *results, u64 tags, ProcCallingConvention calling_convention) {
  907. AstNode *result = make_ast_node(f, AstNode_ProcType);
  908. result->ProcType.token = token;
  909. result->ProcType.params = params;
  910. result->ProcType.results = results;
  911. result->ProcType.tags = tags;
  912. result->ProcType.calling_convention = calling_convention;
  913. return result;
  914. }
  915. AstNode *ast_pointer_type(AstFile *f, Token token, AstNode *type) {
  916. AstNode *result = make_ast_node(f, AstNode_PointerType);
  917. result->PointerType.token = token;
  918. result->PointerType.type = type;
  919. return result;
  920. }
  921. AstNode *ast_array_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
  922. AstNode *result = make_ast_node(f, AstNode_ArrayType);
  923. result->ArrayType.token = token;
  924. result->ArrayType.count = count;
  925. result->ArrayType.elem = elem;
  926. return result;
  927. }
  928. AstNode *ast_dynamic_array_type(AstFile *f, Token token, AstNode *elem) {
  929. AstNode *result = make_ast_node(f, AstNode_DynamicArrayType);
  930. result->DynamicArrayType.token = token;
  931. result->DynamicArrayType.elem = elem;
  932. return result;
  933. }
  934. AstNode *ast_vector_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
  935. AstNode *result = make_ast_node(f, AstNode_VectorType);
  936. result->VectorType.token = token;
  937. result->VectorType.count = count;
  938. result->VectorType.elem = elem;
  939. return result;
  940. }
  941. AstNode *ast_struct_type(AstFile *f, Token token, AstNodeArray fields, isize field_count,
  942. bool is_packed, bool is_ordered, AstNode *align) {
  943. AstNode *result = make_ast_node(f, AstNode_StructType);
  944. result->StructType.token = token;
  945. result->StructType.fields = fields;
  946. result->StructType.field_count = field_count;
  947. result->StructType.is_packed = is_packed;
  948. result->StructType.is_ordered = is_ordered;
  949. result->StructType.align = align;
  950. return result;
  951. }
  952. AstNode *ast_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count, AstNodeArray variants) {
  953. AstNode *result = make_ast_node(f, AstNode_UnionType);
  954. result->UnionType.token = token;
  955. result->UnionType.fields = fields;
  956. result->UnionType.field_count = field_count;
  957. result->UnionType.variants = variants;
  958. return result;
  959. }
  960. AstNode *ast_raw_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count) {
  961. AstNode *result = make_ast_node(f, AstNode_RawUnionType);
  962. result->RawUnionType.token = token;
  963. result->RawUnionType.fields = fields;
  964. result->RawUnionType.field_count = field_count;
  965. return result;
  966. }
  967. AstNode *ast_enum_type(AstFile *f, Token token, AstNode *base_type, AstNodeArray fields) {
  968. AstNode *result = make_ast_node(f, AstNode_EnumType);
  969. result->EnumType.token = token;
  970. result->EnumType.base_type = base_type;
  971. result->EnumType.fields = fields;
  972. return result;
  973. }
  974. AstNode *ast_map_type(AstFile *f, Token token, AstNode *count, AstNode *key, AstNode *value) {
  975. AstNode *result = make_ast_node(f, AstNode_MapType);
  976. result->MapType.token = token;
  977. result->MapType.count = count;
  978. result->MapType.key = key;
  979. result->MapType.value = value;
  980. return result;
  981. }
  982. AstNode *ast_value_decl(AstFile *f, bool is_var, AstNodeArray names, AstNode *type, AstNodeArray values) {
  983. AstNode *result = make_ast_node(f, AstNode_ValueDecl);
  984. result->ValueDecl.is_var = is_var;
  985. result->ValueDecl.names = names;
  986. result->ValueDecl.type = type;
  987. result->ValueDecl.values = values;
  988. return result;
  989. }
  990. AstNode *ast_import_decl(AstFile *f, Token token, bool is_import, Token relpath, Token import_name, AstNode *cond) {
  991. AstNode *result = make_ast_node(f, AstNode_ImportDecl);
  992. result->ImportDecl.token = token;
  993. result->ImportDecl.is_import = is_import;
  994. result->ImportDecl.relpath = relpath;
  995. result->ImportDecl.import_name = import_name;
  996. result->ImportDecl.cond = cond;
  997. return result;
  998. }
  999. AstNode *ast_foreign_library(AstFile *f, Token token, Token filepath, Token library_name, AstNode *cond, bool is_system) {
  1000. AstNode *result = make_ast_node(f, AstNode_ForeignLibrary);
  1001. result->ForeignLibrary.token = token;
  1002. result->ForeignLibrary.filepath = filepath;
  1003. result->ForeignLibrary.library_name = library_name;
  1004. result->ForeignLibrary.cond = cond;
  1005. result->ForeignLibrary.is_system = is_system;
  1006. return result;
  1007. }
  1008. AstNode *ast_label_decl(AstFile *f, Token token, AstNode *name) {
  1009. AstNode *result = make_ast_node(f, AstNode_Label);
  1010. result->Label.token = token;
  1011. result->Label.name = name;
  1012. return result;
  1013. }
  1014. bool next_token(AstFile *f) {
  1015. Token prev = f->curr_token;
  1016. if (f->curr_token_index+1 < f->tokens.count) {
  1017. if (f->curr_token.kind != Token_Comment) {
  1018. f->prev_token = f->curr_token;
  1019. }
  1020. f->curr_token_index++;
  1021. f->curr_token = f->tokens.e[f->curr_token_index];
  1022. if (f->curr_token.kind == Token_Comment) {
  1023. return next_token(f);
  1024. }
  1025. return true;
  1026. }
  1027. syntax_error(f->curr_token, "Token is EOF");
  1028. return false;
  1029. }
  1030. TokenKind look_ahead_token_kind(AstFile *f, isize amount) {
  1031. GB_ASSERT(amount > 0);
  1032. TokenKind kind = Token_Invalid;
  1033. isize index = f->curr_token_index;
  1034. while (amount > 0) {
  1035. index++;
  1036. kind = f->tokens.e[index].kind;
  1037. if (kind != Token_Comment) {
  1038. amount--;
  1039. }
  1040. }
  1041. return kind;
  1042. }
  1043. Token expect_token(AstFile *f, TokenKind kind) {
  1044. Token prev = f->curr_token;
  1045. if (prev.kind != kind) {
  1046. String p = token_strings[prev.kind];
  1047. syntax_error(f->curr_token, "Expected `%.*s`, got `%.*s`",
  1048. LIT(token_strings[kind]),
  1049. LIT(token_strings[prev.kind]));
  1050. }
  1051. next_token(f);
  1052. return prev;
  1053. }
  1054. Token expect_token_after(AstFile *f, TokenKind kind, char *msg) {
  1055. Token prev = f->curr_token;
  1056. if (prev.kind != kind) {
  1057. String p = token_strings[prev.kind];
  1058. syntax_error(f->curr_token, "Expected `%.*s` after %s, got `%.*s`",
  1059. LIT(token_strings[kind]),
  1060. msg,
  1061. LIT(p));
  1062. }
  1063. next_token(f);
  1064. return prev;
  1065. }
  1066. Token expect_operator(AstFile *f) {
  1067. Token prev = f->curr_token;
  1068. if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
  1069. syntax_error(f->curr_token, "Expected an operator, got `%.*s`",
  1070. LIT(token_strings[prev.kind]));
  1071. }
  1072. next_token(f);
  1073. return prev;
  1074. }
  1075. Token expect_keyword(AstFile *f) {
  1076. Token prev = f->curr_token;
  1077. if (!gb_is_between(prev.kind, Token__KeywordBegin+1, Token__KeywordEnd-1)) {
  1078. syntax_error(f->curr_token, "Expected a keyword, got `%.*s`",
  1079. LIT(token_strings[prev.kind]));
  1080. }
  1081. next_token(f);
  1082. return prev;
  1083. }
  1084. bool allow_token(AstFile *f, TokenKind kind) {
  1085. Token prev = f->curr_token;
  1086. if (prev.kind == kind) {
  1087. next_token(f);
  1088. return true;
  1089. }
  1090. return false;
  1091. }
  1092. bool is_blank_ident(String str) {
  1093. if (str.len == 1) {
  1094. return str.text[0] == '_';
  1095. }
  1096. return false;
  1097. }
  1098. // NOTE(bill): Go to next statement to prevent numerous error messages popping up
  1099. void fix_advance_to_next_stmt(AstFile *f) {
  1100. // TODO(bill): fix_advance_to_next_stmt
  1101. #if 1
  1102. for (;;) {
  1103. Token t = f->curr_token;
  1104. switch (t.kind) {
  1105. case Token_EOF:
  1106. case Token_Semicolon:
  1107. return;
  1108. case Token_if:
  1109. case Token_when:
  1110. case Token_return:
  1111. case Token_match:
  1112. case Token_defer:
  1113. case Token_asm:
  1114. case Token_using:
  1115. // case Token_thread_local:
  1116. case Token_no_alias:
  1117. // case Token_immutable:
  1118. case Token_break:
  1119. case Token_continue:
  1120. case Token_fallthrough:
  1121. case Token_push_allocator:
  1122. case Token_push_context:
  1123. case Token_Hash:
  1124. {
  1125. if (token_pos_eq(t.pos, f->fix_prev_pos) &&
  1126. f->fix_count < PARSER_MAX_FIX_COUNT) {
  1127. f->fix_count++;
  1128. return;
  1129. }
  1130. if (token_pos_cmp(f->fix_prev_pos, t.pos) < 0) {
  1131. f->fix_prev_pos = t.pos;
  1132. f->fix_count = 0; // NOTE(bill): Reset
  1133. return;
  1134. }
  1135. // NOTE(bill): Reaching here means there is a parsing bug
  1136. } break;
  1137. }
  1138. next_token(f);
  1139. }
  1140. #endif
  1141. }
  1142. Token expect_closing(AstFile *f, TokenKind kind, String context) {
  1143. if (f->curr_token.kind != kind &&
  1144. f->curr_token.kind == Token_Semicolon &&
  1145. str_eq(f->curr_token.string, str_lit("\n"))) {
  1146. error(f->curr_token, "Missing `,` before newline in %.*s", LIT(context));
  1147. next_token(f);
  1148. }
  1149. return expect_token(f, kind);
  1150. }
  1151. bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
  1152. if (s == NULL) {
  1153. return false;
  1154. }
  1155. switch (s->kind) {
  1156. case AstNode_HelperType:
  1157. return is_semicolon_optional_for_node(f, s->HelperType.type);
  1158. case AstNode_PointerType:
  1159. return is_semicolon_optional_for_node(f, s->PointerType.type);
  1160. case AstNode_StructType:
  1161. case AstNode_UnionType:
  1162. case AstNode_RawUnionType:
  1163. case AstNode_EnumType:
  1164. return true;
  1165. case AstNode_ProcLit:
  1166. return s->ProcLit.body != NULL;
  1167. case AstNode_ValueDecl:
  1168. if (!s->ValueDecl.is_var) {
  1169. if (s->ValueDecl.values.count > 0) {
  1170. AstNode *last = s->ValueDecl.values.e[s->ValueDecl.values.count-1];
  1171. return is_semicolon_optional_for_node(f, last);
  1172. }
  1173. }
  1174. break;
  1175. }
  1176. return false;
  1177. }
  1178. void expect_semicolon(AstFile *f, AstNode *s) {
  1179. if (allow_token(f, Token_Semicolon)) {
  1180. return;
  1181. }
  1182. Token prev_token = f->prev_token;
  1183. switch (f->curr_token.kind) {
  1184. case Token_EOF:
  1185. return;
  1186. }
  1187. if (s != NULL) {
  1188. if (prev_token.pos.line != f->curr_token.pos.line) {
  1189. if (is_semicolon_optional_for_node(f, s)) {
  1190. return;
  1191. }
  1192. } else {
  1193. // switch (s->kind) {
  1194. // case AstNode_GiveExpr:
  1195. // if (f->curr_token.kind == Token_CloseBrace) {
  1196. // return;
  1197. // }
  1198. // break;
  1199. // }
  1200. }
  1201. syntax_error(prev_token, "Expected `;` after %.*s, got %.*s",
  1202. LIT(ast_node_strings[s->kind]), LIT(token_strings[prev_token.kind]));
  1203. } else {
  1204. syntax_error(prev_token, "Expected `;`");
  1205. }
  1206. fix_advance_to_next_stmt(f);
  1207. }
  1208. AstNode * parse_expr(AstFile *f, bool lhs);
  1209. AstNode * parse_proc_type(AstFile *f, AstNode **foreign_library, String *foreign_name, String *link_name);
  1210. AstNodeArray parse_stmt_list(AstFile *f);
  1211. AstNode * parse_stmt(AstFile *f);
  1212. AstNode * parse_body(AstFile *f);
  1213. AstNode *parse_ident(AstFile *f) {
  1214. Token token = f->curr_token;
  1215. if (token.kind == Token_Ident) {
  1216. next_token(f);
  1217. } else {
  1218. token.string = str_lit("_");
  1219. expect_token(f, Token_Ident);
  1220. }
  1221. return ast_ident(f, token);
  1222. }
  1223. AstNode *parse_tag_expr(AstFile *f, AstNode *expression) {
  1224. Token token = expect_token(f, Token_Hash);
  1225. Token name = expect_token(f, Token_Ident);
  1226. return ast_tag_expr(f, token, name, expression);
  1227. }
  1228. AstNode *unparen_expr(AstNode *node) {
  1229. for (;;) {
  1230. if (node == NULL) {
  1231. return NULL;
  1232. }
  1233. if (node->kind != AstNode_ParenExpr) {
  1234. return node;
  1235. }
  1236. node = node->ParenExpr.expr;
  1237. }
  1238. }
  1239. AstNode *parse_value(AstFile *f);
  1240. AstNodeArray parse_element_list(AstFile *f) {
  1241. AstNodeArray elems = make_ast_node_array(f);
  1242. while (f->curr_token.kind != Token_CloseBrace &&
  1243. f->curr_token.kind != Token_EOF) {
  1244. AstNode *elem = parse_value(f);
  1245. if (f->curr_token.kind == Token_Eq) {
  1246. Token eq = expect_token(f, Token_Eq);
  1247. AstNode *value = parse_value(f);
  1248. elem = ast_field_value(f, elem, value, eq);
  1249. }
  1250. array_add(&elems, elem);
  1251. if (!allow_token(f, Token_Comma)) {
  1252. break;
  1253. }
  1254. }
  1255. return elems;
  1256. }
  1257. AstNode *parse_literal_value(AstFile *f, AstNode *type) {
  1258. AstNodeArray elems = {0};
  1259. Token open = expect_token(f, Token_OpenBrace);
  1260. f->expr_level++;
  1261. if (f->curr_token.kind != Token_CloseBrace) {
  1262. elems = parse_element_list(f);
  1263. }
  1264. f->expr_level--;
  1265. Token close = expect_closing(f, Token_CloseBrace, str_lit("compound literal"));
  1266. return ast_compound_lit(f, type, elems, open, close);
  1267. }
  1268. AstNode *parse_value(AstFile *f) {
  1269. if (f->curr_token.kind == Token_OpenBrace) {
  1270. return parse_literal_value(f, NULL);
  1271. }
  1272. AstNode *value = parse_expr(f, false);
  1273. return value;
  1274. }
  1275. AstNode *parse_type_or_ident(AstFile *f);
  1276. void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) {
  1277. if (*tags & tag) {
  1278. syntax_error_node(tag_expr, "Procedure tag already used: %.*s", LIT(tag_name));
  1279. }
  1280. *tags |= tag;
  1281. }
  1282. bool is_foreign_name_valid(String name) {
  1283. // TODO(bill): is_foreign_name_valid
  1284. if (name.len == 0)
  1285. return false;
  1286. isize offset = 0;
  1287. while (offset < name.len) {
  1288. Rune rune;
  1289. isize remaining = name.len - offset;
  1290. isize width = gb_utf8_decode(name.text+offset, remaining, &rune);
  1291. if (rune == GB_RUNE_INVALID && width == 1) {
  1292. return false;
  1293. } else if (rune == GB_RUNE_BOM && remaining > 0) {
  1294. return false;
  1295. }
  1296. if (offset == 0) {
  1297. switch (rune) {
  1298. case '-':
  1299. case '$':
  1300. case '.':
  1301. case '_':
  1302. break;
  1303. default:
  1304. if (!gb_char_is_alpha(cast(char)rune))
  1305. return false;
  1306. break;
  1307. }
  1308. } else {
  1309. switch (rune) {
  1310. case '-':
  1311. case '$':
  1312. case '.':
  1313. case '_':
  1314. break;
  1315. default:
  1316. if (!gb_char_is_alphanumeric(cast(char)rune)) {
  1317. return false;
  1318. }
  1319. break;
  1320. }
  1321. }
  1322. offset += width;
  1323. }
  1324. return true;
  1325. }
  1326. void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, String *foreign_name, String *link_name, ProcCallingConvention *calling_convention) {
  1327. // TODO(bill): Add this to procedure literals too
  1328. GB_ASSERT(tags != NULL);
  1329. GB_ASSERT(link_name != NULL);
  1330. GB_ASSERT(link_name != NULL);
  1331. ProcCallingConvention cc = ProcCC_Invalid;
  1332. while (f->curr_token.kind == Token_Hash) {
  1333. AstNode *tag_expr = parse_tag_expr(f, NULL);
  1334. ast_node(te, TagExpr, tag_expr);
  1335. String tag_name = te->name.string;
  1336. #define ELSE_IF_ADD_TAG(name) \
  1337. else if (str_eq(tag_name, str_lit(#name))) { \
  1338. check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
  1339. }
  1340. if (str_eq(tag_name, str_lit("foreign"))) {
  1341. check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
  1342. *foreign_library_token = parse_ident(f);
  1343. if (f->curr_token.kind == Token_String) {
  1344. *foreign_name = f->curr_token.string;
  1345. // TODO(bill): Check if valid string
  1346. if (!is_foreign_name_valid(*foreign_name)) {
  1347. syntax_error_node(tag_expr, "Invalid alternative foreign procedure name: `%.*s`", LIT(*foreign_name));
  1348. }
  1349. next_token(f);
  1350. }
  1351. } else if (str_eq(tag_name, str_lit("link_name"))) {
  1352. check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name);
  1353. if (f->curr_token.kind == Token_String) {
  1354. *link_name = f->curr_token.string;
  1355. // TODO(bill): Check if valid string
  1356. if (!is_foreign_name_valid(*link_name)) {
  1357. syntax_error_node(tag_expr, "Invalid alternative link procedure name `%.*s`", LIT(*link_name));
  1358. }
  1359. next_token(f);
  1360. } else {
  1361. expect_token(f, Token_String);
  1362. }
  1363. }
  1364. ELSE_IF_ADD_TAG(export)
  1365. ELSE_IF_ADD_TAG(bounds_check)
  1366. ELSE_IF_ADD_TAG(no_bounds_check)
  1367. ELSE_IF_ADD_TAG(inline)
  1368. ELSE_IF_ADD_TAG(no_inline)
  1369. // ELSE_IF_ADD_TAG(dll_import)
  1370. // ELSE_IF_ADD_TAG(dll_export)
  1371. else if (str_eq(tag_name, str_lit("cc_odin"))) {
  1372. if (cc == ProcCC_Invalid) {
  1373. cc = ProcCC_Odin;
  1374. } else {
  1375. syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
  1376. }
  1377. } else if (str_eq(tag_name, str_lit("cc_c"))) {
  1378. if (cc == ProcCC_Invalid) {
  1379. cc = ProcCC_C;
  1380. } else {
  1381. syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
  1382. }
  1383. } else if (str_eq(tag_name, str_lit("cc_std"))) {
  1384. if (cc == ProcCC_Invalid) {
  1385. cc = ProcCC_Std;
  1386. } else {
  1387. syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
  1388. }
  1389. } else if (str_eq(tag_name, str_lit("cc_fast"))) {
  1390. if (cc == ProcCC_Invalid) {
  1391. cc = ProcCC_Fast;
  1392. } else {
  1393. syntax_error_node(tag_expr, "Multiple calling conventions for procedure type");
  1394. }
  1395. } else {
  1396. syntax_error_node(tag_expr, "Unknown procedure tag #%.*s\n", LIT(tag_name));
  1397. }
  1398. #undef ELSE_IF_ADD_TAG
  1399. }
  1400. if (cc == ProcCC_Invalid) {
  1401. if ((*tags) & ProcTag_foreign) {
  1402. cc = ProcCC_C;
  1403. } else {
  1404. cc = ProcCC_Odin;
  1405. }
  1406. }
  1407. if (calling_convention) {
  1408. *calling_convention = cc;
  1409. }
  1410. if ((*tags & ProcTag_foreign) && (*tags & ProcTag_export)) {
  1411. syntax_error(f->curr_token, "You cannot apply both #foreign and #export to a procedure");
  1412. }
  1413. if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) {
  1414. syntax_error(f->curr_token, "You cannot apply both #inline and #no_inline to a procedure");
  1415. }
  1416. if ((*tags & ProcTag_bounds_check) && (*tags & ProcTag_no_bounds_check)) {
  1417. syntax_error(f->curr_token, "You cannot apply both #bounds_check and #no_bounds_check to a procedure");
  1418. }
  1419. if (((*tags & ProcTag_bounds_check) || (*tags & ProcTag_no_bounds_check)) && (*tags & ProcTag_foreign)) {
  1420. syntax_error(f->curr_token, "You cannot apply both #bounds_check or #no_bounds_check to a procedure without a body");
  1421. }
  1422. }
  1423. AstNodeArray parse_lhs_expr_list(AstFile *f);
  1424. AstNodeArray parse_rhs_expr_list(AstFile *f);
  1425. AstNode * parse_simple_stmt (AstFile *f, bool in_stmt_ok);
  1426. AstNode * parse_type (AstFile *f);
  1427. AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
  1428. if (statement == NULL) {
  1429. return NULL;
  1430. }
  1431. if (statement->kind == AstNode_ExprStmt) {
  1432. return statement->ExprStmt.expr;
  1433. }
  1434. syntax_error(f->curr_token, "Expected `%.*s`, found a simple statement.", LIT(kind));
  1435. return ast_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
  1436. }
  1437. // AstNode *parse_block_expr(AstFile *f) {
  1438. // AstNodeArray stmts = {0};
  1439. // Token open, close;
  1440. // open = expect_token(f, Token_OpenBrace);
  1441. // f->expr_level++;
  1442. // stmts = parse_stmt_list(f);
  1443. // f->expr_level--;
  1444. // close = expect_token(f, Token_CloseBrace);
  1445. // return ast_block_expr(f, stmts, open, close);
  1446. // }
  1447. // AstNode *parse_if_expr(AstFile *f) {
  1448. // if (f->curr_proc == NULL) {
  1449. // syntax_error(f->curr_token, "You cannot use an if expression in the file scope");
  1450. // return ast_bad_stmt(f, f->curr_token, f->curr_token);
  1451. // }
  1452. // Token token = expect_token(f, Token_if);
  1453. // AstNode *init = NULL;
  1454. // AstNode *cond = NULL;
  1455. // AstNode *body = NULL;
  1456. // AstNode *else_expr = NULL;
  1457. // isize prev_level = f->expr_level;
  1458. // f->expr_level = -1;
  1459. // if (allow_token(f, Token_Semicolon)) {
  1460. // cond = parse_expr(f, false);
  1461. // } else {
  1462. // init = parse_simple_stmt(f, false);
  1463. // if (allow_token(f, Token_Semicolon)) {
  1464. // cond = parse_expr(f, false);
  1465. // } else {
  1466. // cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
  1467. // init = NULL;
  1468. // }
  1469. // }
  1470. // f->expr_level = prev_level;
  1471. // if (cond == NULL) {
  1472. // syntax_error(f->curr_token, "Expected condition for if statement");
  1473. // }
  1474. // body = parse_block_expr(f);
  1475. // if (allow_token(f, Token_else)) {
  1476. // switch (f->curr_token.kind) {
  1477. // case Token_if:
  1478. // else_expr = parse_if_expr(f);
  1479. // break;
  1480. // case Token_OpenBrace:
  1481. // else_expr = parse_block_expr(f);
  1482. // break;
  1483. // default:
  1484. // syntax_error(f->curr_token, "Expected if expression block statement");
  1485. // else_expr = ast_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
  1486. // break;
  1487. // }
  1488. // } else {
  1489. // syntax_error(f->curr_token, "An if expression must have an else clause");
  1490. // return ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
  1491. // }
  1492. // return ast_if_expr(f, token, init, cond, body, else_expr);
  1493. // }
  1494. AstNode *parse_operand(AstFile *f, bool lhs) {
  1495. AstNode *operand = NULL; // Operand
  1496. switch (f->curr_token.kind) {
  1497. case Token_Ident:
  1498. operand = parse_ident(f);
  1499. if (!lhs) {
  1500. // TODO(bill): Handle?
  1501. }
  1502. return operand;
  1503. case Token_context:
  1504. return ast_implicit(f, expect_token(f, Token_context));
  1505. case Token_Integer:
  1506. case Token_Float:
  1507. case Token_Imag:
  1508. case Token_Rune:
  1509. operand = ast_basic_lit(f, f->curr_token);
  1510. next_token(f);
  1511. return operand;
  1512. case Token_String: {
  1513. Token token = f->curr_token;
  1514. next_token(f);
  1515. if (f->curr_token.kind == Token_String) {
  1516. // NOTE(bill): Allow neighbouring string literals to be merge together to
  1517. // become one big string
  1518. String s = f->curr_token.string;
  1519. Array(u8) data;
  1520. array_init_reserve(&data, heap_allocator(), token.string.len+s.len);
  1521. gb_memmove(data.e, token.string.text, token.string.len);
  1522. data.count += token.string.len;
  1523. while (f->curr_token.kind == Token_String) {
  1524. String s = f->curr_token.string;
  1525. isize old_count = data.count;
  1526. array_resize(&data, data.count + s.len);
  1527. gb_memmove(data.e+old_count, s.text, s.len);
  1528. next_token(f);
  1529. }
  1530. token.string = make_string(data.e, data.count);
  1531. array_add(&f->tokenizer.allocated_strings, token.string);
  1532. }
  1533. return ast_basic_lit(f, token);
  1534. }
  1535. case Token_OpenParen: {
  1536. Token open, close;
  1537. // NOTE(bill): Skip the Paren Expression
  1538. open = expect_token(f, Token_OpenParen);
  1539. f->expr_level++;
  1540. operand = parse_expr(f, false);
  1541. f->expr_level--;
  1542. close = expect_token(f, Token_CloseParen);
  1543. return ast_paren_expr(f, operand, open, close);
  1544. }
  1545. case Token_Hash: {
  1546. Token token = expect_token(f, Token_Hash);
  1547. Token name = expect_token(f, Token_Ident);
  1548. if (str_eq(name.string, str_lit("run"))) {
  1549. AstNode *expr = parse_expr(f, false);
  1550. operand = ast_run_expr(f, token, name, expr);
  1551. if (unparen_expr(expr)->kind != AstNode_CallExpr) {
  1552. error_node(expr, "#run can only be applied to procedure calls");
  1553. operand = ast_bad_expr(f, token, f->curr_token);
  1554. }
  1555. warning(token, "#run is not yet implemented");
  1556. } else if (str_eq(name.string, str_lit("file"))) { return ast_basic_directive(f, token, name.string);
  1557. } else if (str_eq(name.string, str_lit("line"))) { return ast_basic_directive(f, token, name.string);
  1558. } else if (str_eq(name.string, str_lit("procedure"))) { return ast_basic_directive(f, token, name.string);
  1559. } else if (str_eq(name.string, str_lit("type"))) { return ast_helper_type(f, token, parse_type(f));
  1560. } else if (!lhs && str_eq(name.string, str_lit("alias"))) { return ast_alias(f, token, parse_expr(f, false));
  1561. } else {
  1562. operand = ast_tag_expr(f, token, name, parse_expr(f, false));
  1563. }
  1564. return operand;
  1565. }
  1566. // Parse Procedure Type or Literal
  1567. case Token_proc: {
  1568. Token token = f->curr_token;
  1569. AstNode *foreign_library = NULL;
  1570. String foreign_name = {0};
  1571. String link_name = {0};
  1572. AstNode *type = parse_proc_type(f, &foreign_library, &foreign_name, &link_name);
  1573. u64 tags = type->ProcType.tags;
  1574. if (f->curr_token.kind == Token_OpenBrace) {
  1575. if ((tags & ProcTag_foreign) != 0) {
  1576. syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
  1577. }
  1578. AstNode *curr_proc = f->curr_proc;
  1579. AstNode *body = NULL;
  1580. f->curr_proc = type;
  1581. body = parse_body(f);
  1582. f->curr_proc = curr_proc;
  1583. return ast_proc_lit(f, type, body, tags, foreign_library, foreign_name, link_name);
  1584. }
  1585. if ((tags & ProcTag_foreign) != 0) {
  1586. return ast_proc_lit(f, type, NULL, tags, foreign_library, foreign_name, link_name);
  1587. }
  1588. if (tags != 0) {
  1589. syntax_error(token, "A procedure type cannot have tags");
  1590. }
  1591. return type;
  1592. }
  1593. // case Token_if:
  1594. // if (!lhs && f->expr_level >= 0) {
  1595. // return parse_if_expr(f);
  1596. // }
  1597. // break;
  1598. // case Token_OpenBrace:
  1599. // if (!lhs && f->expr_level >= 0) {
  1600. // return parse_block_expr(f);
  1601. // }
  1602. // break;
  1603. default: {
  1604. AstNode *type = parse_type_or_ident(f);
  1605. if (type != NULL) {
  1606. // TODO(bill): Is this correct???
  1607. // NOTE(bill): Sanity check as identifiers should be handled already
  1608. TokenPos pos = ast_node_token(type).pos;
  1609. GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type cannot be identifier %.*s(%td:%td)", LIT(pos.file), pos.line, pos.column);
  1610. return type;
  1611. }
  1612. break;
  1613. }
  1614. }
  1615. Token begin = f->curr_token;
  1616. syntax_error(begin, "Expected an operand");
  1617. fix_advance_to_next_stmt(f);
  1618. return ast_bad_expr(f, begin, f->curr_token);
  1619. }
  1620. bool is_literal_type(AstNode *node) {
  1621. node = unparen_expr(node);
  1622. switch (node->kind) {
  1623. case AstNode_BadExpr:
  1624. case AstNode_Ident:
  1625. case AstNode_SelectorExpr:
  1626. case AstNode_ArrayType:
  1627. case AstNode_VectorType:
  1628. case AstNode_StructType:
  1629. case AstNode_DynamicArrayType:
  1630. case AstNode_MapType:
  1631. return true;
  1632. }
  1633. return false;
  1634. }
  1635. AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
  1636. AstNodeArray args = make_ast_node_array(f);
  1637. Token open_paren, close_paren;
  1638. Token ellipsis = {0};
  1639. f->expr_level++;
  1640. open_paren = expect_token(f, Token_OpenParen);
  1641. while (f->curr_token.kind != Token_CloseParen &&
  1642. f->curr_token.kind != Token_EOF &&
  1643. ellipsis.pos.line == 0) {
  1644. if (f->curr_token.kind == Token_Comma) {
  1645. syntax_error(f->curr_token, "Expected an expression not a ,");
  1646. }
  1647. if (f->curr_token.kind == Token_Ellipsis) {
  1648. ellipsis = f->curr_token;
  1649. next_token(f);
  1650. }
  1651. AstNode *arg = parse_expr(f, false);
  1652. array_add(&args, arg);
  1653. if (!allow_token(f, Token_Comma)) {
  1654. break;
  1655. }
  1656. }
  1657. f->expr_level--;
  1658. close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list"));
  1659. return ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis);
  1660. }
  1661. AstNode *parse_macro_call_expr(AstFile *f, AstNode *operand) {
  1662. AstNodeArray args = make_ast_node_array(f);
  1663. Token bang, open_paren, close_paren;
  1664. bang = expect_token(f, Token_Not);
  1665. f->expr_level++;
  1666. open_paren = expect_token(f, Token_OpenParen);
  1667. while (f->curr_token.kind != Token_CloseParen &&
  1668. f->curr_token.kind != Token_EOF) {
  1669. if (f->curr_token.kind == Token_Comma) {
  1670. syntax_error(f->curr_token, "Expected an expression not a ,");
  1671. }
  1672. AstNode *arg = parse_expr(f, false);
  1673. array_add(&args, arg);
  1674. if (!allow_token(f, Token_Comma)) {
  1675. break;
  1676. }
  1677. }
  1678. f->expr_level--;
  1679. close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list"));
  1680. return ast_macro_call_expr(f, operand, bang, args, open_paren, close_paren);
  1681. }
  1682. AstNode *parse_atom_expr(AstFile *f, bool lhs) {
  1683. AstNode *operand = parse_operand(f, lhs);
  1684. bool loop = true;
  1685. while (loop) {
  1686. switch (f->curr_token.kind) {
  1687. case Token_OpenParen:
  1688. operand = parse_call_expr(f, operand);
  1689. break;
  1690. case Token_Not:
  1691. operand = parse_macro_call_expr(f, operand);
  1692. break;
  1693. case Token_Period: {
  1694. Token token = f->curr_token;
  1695. next_token(f);
  1696. switch (f->curr_token.kind) {
  1697. case Token_Ident:
  1698. operand = ast_selector_expr(f, token, operand, parse_ident(f));
  1699. break;
  1700. // case Token_Integer:
  1701. // operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
  1702. // break;
  1703. default:
  1704. syntax_error(f->curr_token, "Expected a selector");
  1705. next_token(f);
  1706. operand = ast_bad_expr(f, ast_node_token(operand), f->curr_token);
  1707. // operand = ast_selector_expr(f, f->curr_token, operand, NULL);
  1708. break;
  1709. }
  1710. } break;
  1711. case Token_OpenBracket: {
  1712. if (lhs) {
  1713. // TODO(bill): Handle this
  1714. }
  1715. Token open = {0}, close = {0}, interval = {0};
  1716. AstNode *indices[3] = {0};
  1717. isize ellipsis_count = 0;
  1718. Token ellipses[2] = {0};
  1719. f->expr_level++;
  1720. open = expect_token(f, Token_OpenBracket);
  1721. if (f->curr_token.kind != Token_Ellipsis) {
  1722. indices[0] = parse_expr(f, false);
  1723. }
  1724. bool is_index = true;
  1725. while (f->curr_token.kind == Token_Ellipsis && ellipsis_count < gb_count_of(ellipses)) {
  1726. ellipses[ellipsis_count++] = f->curr_token;
  1727. next_token(f);
  1728. if (f->curr_token.kind != Token_Ellipsis &&
  1729. f->curr_token.kind != Token_CloseBracket &&
  1730. f->curr_token.kind != Token_EOF) {
  1731. indices[ellipsis_count] = parse_expr(f, false);
  1732. }
  1733. }
  1734. f->expr_level--;
  1735. close = expect_token(f, Token_CloseBracket);
  1736. if (ellipsis_count > 0) {
  1737. bool index3 = false;
  1738. if (ellipsis_count == 2) {
  1739. index3 = true;
  1740. // 2nd and 3rd index must be present
  1741. if (indices[1] == NULL) {
  1742. error(ellipses[0], "2nd index required in 3-index slice expression");
  1743. indices[1] = ast_bad_expr(f, ellipses[0], ellipses[1]);
  1744. }
  1745. if (indices[2] == NULL) {
  1746. error(ellipses[1], "3rd index required in 3-index slice expression");
  1747. indices[2] = ast_bad_expr(f, ellipses[1], close);
  1748. }
  1749. }
  1750. operand = ast_slice_expr(f, operand, open, close, index3, indices[0], indices[1], indices[2]);
  1751. } else {
  1752. operand = ast_index_expr(f, operand, indices[0], open, close);
  1753. }
  1754. } break;
  1755. case Token_Pointer: // Deference
  1756. operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
  1757. break;
  1758. case Token_OpenBrace:
  1759. if (!lhs && is_literal_type(operand) && f->expr_level >= 0) {
  1760. operand = parse_literal_value(f, operand);
  1761. } else {
  1762. loop = false;
  1763. }
  1764. break;
  1765. default:
  1766. loop = false;
  1767. break;
  1768. }
  1769. lhs = false; // NOTE(bill): 'tis not lhs anymore
  1770. }
  1771. return operand;
  1772. }
  1773. AstNode *parse_unary_expr(AstFile *f, bool lhs) {
  1774. switch (f->curr_token.kind) {
  1775. case Token_cast:
  1776. case Token_transmute:
  1777. case Token_down_cast:
  1778. case Token_union_cast:
  1779. {
  1780. Token token = f->curr_token; next_token(f);
  1781. Token open = expect_token(f, Token_OpenParen);
  1782. AstNode *type = parse_type(f);
  1783. Token close = expect_token(f, Token_CloseParen);
  1784. AstNode *expr = parse_unary_expr(f, lhs);
  1785. return ast_cast_expr(f, token, type, expr, open, close);
  1786. } break;
  1787. case Token_Pointer: {
  1788. Token op = f->curr_token;
  1789. next_token(f);
  1790. AstNode *expr = parse_unary_expr(f, lhs);
  1791. if (is_ast_node_type(expr)) {
  1792. return ast_pointer_type(f, op, expr);
  1793. }
  1794. return ast_unary_expr(f, op, expr);
  1795. } break;
  1796. // case Token_Maybe:
  1797. case Token_Add:
  1798. case Token_Sub:
  1799. case Token_Not:
  1800. case Token_Xor: {
  1801. Token op = f->curr_token;
  1802. next_token(f);
  1803. return ast_unary_expr(f, op, parse_unary_expr(f, lhs));
  1804. } break;
  1805. }
  1806. return parse_atom_expr(f, lhs);
  1807. }
  1808. // NOTE(bill): result == priority
  1809. i32 token_precedence(TokenKind t) {
  1810. switch (t) {
  1811. case Token_Question:
  1812. return 1;
  1813. case Token_CmpOr:
  1814. return 2;
  1815. case Token_CmpAnd:
  1816. return 3;
  1817. case Token_CmpEq:
  1818. case Token_NotEq:
  1819. case Token_Lt:
  1820. case Token_Gt:
  1821. case Token_LtEq:
  1822. case Token_GtEq:
  1823. return 4;
  1824. case Token_Add:
  1825. case Token_Sub:
  1826. case Token_Or:
  1827. case Token_Xor:
  1828. return 5;
  1829. case Token_Mul:
  1830. case Token_Quo:
  1831. case Token_Mod:
  1832. case Token_And:
  1833. case Token_AndNot:
  1834. case Token_Shl:
  1835. case Token_Shr:
  1836. return 6;
  1837. }
  1838. return 0;
  1839. }
  1840. AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
  1841. AstNode *expr = parse_unary_expr(f, lhs);
  1842. for (i32 prec = token_precedence(f->curr_token.kind); prec >= prec_in; prec--) {
  1843. for (;;) {
  1844. Token op = f->curr_token;
  1845. i32 op_prec = token_precedence(op.kind);
  1846. if (op_prec != prec) {
  1847. // NOTE(bill): This will also catch operators that are not valid "binary" operators
  1848. break;
  1849. }
  1850. expect_operator(f); // NOTE(bill): error checks too
  1851. if (op.kind == Token_Question) {
  1852. AstNode *cond = expr;
  1853. // Token_Question
  1854. AstNode *x = parse_expr(f, lhs);
  1855. Token token_c = expect_token(f, Token_Colon);
  1856. AstNode *y = parse_expr(f, lhs);
  1857. expr = ast_ternary_expr(f, cond, x, y);
  1858. } else {
  1859. AstNode *right = parse_binary_expr(f, false, prec+1);
  1860. if (!right) {
  1861. syntax_error(op, "Expected expression on the right-hand side of the binary operator");
  1862. }
  1863. expr = ast_binary_expr(f, op, expr, right);
  1864. }
  1865. lhs = false;
  1866. }
  1867. }
  1868. return expr;
  1869. }
  1870. AstNode *parse_expr(AstFile *f, bool lhs) {
  1871. return parse_binary_expr(f, lhs, 0+1);
  1872. }
  1873. AstNodeArray parse_expr_list(AstFile *f, bool lhs) {
  1874. AstNodeArray list = make_ast_node_array(f);
  1875. for (;;) {
  1876. AstNode *e = parse_expr(f, lhs);
  1877. array_add(&list, e);
  1878. if (f->curr_token.kind != Token_Comma ||
  1879. f->curr_token.kind == Token_EOF) {
  1880. break;
  1881. }
  1882. next_token(f);
  1883. }
  1884. return list;
  1885. }
  1886. AstNodeArray parse_lhs_expr_list(AstFile *f) {
  1887. return parse_expr_list(f, true);
  1888. }
  1889. AstNodeArray parse_rhs_expr_list(AstFile *f) {
  1890. return parse_expr_list(f, false);
  1891. }
  1892. AstNodeArray parse_ident_list(AstFile *f) {
  1893. AstNodeArray list = make_ast_node_array(f);
  1894. do {
  1895. array_add(&list, parse_ident(f));
  1896. if (f->curr_token.kind != Token_Comma ||
  1897. f->curr_token.kind == Token_EOF) {
  1898. break;
  1899. }
  1900. next_token(f);
  1901. } while (true);
  1902. return list;
  1903. }
  1904. AstNode *parse_type_attempt(AstFile *f) {
  1905. AstNode *type = parse_type_or_ident(f);
  1906. if (type != NULL) {
  1907. // TODO(bill): Handle?
  1908. }
  1909. return type;
  1910. }
  1911. AstNode *parse_type(AstFile *f) {
  1912. AstNode *type = parse_type_attempt(f);
  1913. if (type == NULL) {
  1914. Token token = f->curr_token;
  1915. syntax_error(token, "Expected a type");
  1916. next_token(f);
  1917. return ast_bad_expr(f, token, f->curr_token);
  1918. }
  1919. return type;
  1920. }
  1921. AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) {
  1922. AstNode *type = NULL;
  1923. AstNodeArray values = {0};
  1924. bool is_mutable = true;
  1925. if (allow_token(f, Token_Colon)) {
  1926. type = parse_type_attempt(f);
  1927. } else if (f->curr_token.kind != Token_Eq &&
  1928. f->curr_token.kind != Token_Semicolon) {
  1929. syntax_error(f->curr_token, "Expected a type separator `:` or `=`");
  1930. }
  1931. switch (f->curr_token.kind) {
  1932. case Token_Colon:
  1933. is_mutable = false;
  1934. /*fallthrough*/
  1935. case Token_Eq:
  1936. next_token(f);
  1937. values = parse_rhs_expr_list(f);
  1938. if (values.count > lhs.count) {
  1939. syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
  1940. } else if (values.count < lhs.count && !is_mutable) {
  1941. syntax_error(f->curr_token, "All constant declarations must be defined");
  1942. } else if (values.count == 0) {
  1943. syntax_error(f->curr_token, "Expected an expression for this declaration");
  1944. }
  1945. break;
  1946. }
  1947. if (is_mutable) {
  1948. if (type == NULL && values.count == 0) {
  1949. syntax_error(f->curr_token, "Missing variable type or initialization");
  1950. return ast_bad_decl(f, f->curr_token, f->curr_token);
  1951. }
  1952. } else {
  1953. if (type == NULL && values.count == 0 && lhs.count > 0) {
  1954. syntax_error(f->curr_token, "Missing constant value");
  1955. return ast_bad_decl(f, f->curr_token, f->curr_token);
  1956. }
  1957. }
  1958. if (values.e == NULL) {
  1959. values = make_ast_node_array(f);
  1960. }
  1961. AstNodeArray specs = {0};
  1962. array_init_reserve(&specs, heap_allocator(), 1);
  1963. return ast_value_decl(f, is_mutable, lhs, type, values);
  1964. }
  1965. AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
  1966. AstNodeArray lhs = parse_lhs_expr_list(f);
  1967. Token token = f->curr_token;
  1968. switch (token.kind) {
  1969. case Token_Eq:
  1970. case Token_AddEq:
  1971. case Token_SubEq:
  1972. case Token_MulEq:
  1973. case Token_QuoEq:
  1974. case Token_ModEq:
  1975. case Token_AndEq:
  1976. case Token_OrEq:
  1977. case Token_XorEq:
  1978. case Token_ShlEq:
  1979. case Token_ShrEq:
  1980. case Token_AndNotEq:
  1981. case Token_CmpAndEq:
  1982. case Token_CmpOrEq:
  1983. {
  1984. if (f->curr_proc == NULL) {
  1985. syntax_error(f->curr_token, "You cannot use a simple statement in the file scope");
  1986. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  1987. }
  1988. next_token(f);
  1989. AstNodeArray rhs = parse_rhs_expr_list(f);
  1990. if (rhs.count == 0) {
  1991. syntax_error(token, "No right-hand side in assignment statement.");
  1992. return ast_bad_stmt(f, token, f->curr_token);
  1993. }
  1994. return ast_assign_stmt(f, token, lhs, rhs);
  1995. } break;
  1996. case Token_in:
  1997. if (in_stmt_ok) {
  1998. allow_token(f, Token_in);
  1999. AstNode *expr = parse_expr(f, false);
  2000. switch (f->curr_token.kind) {
  2001. case Token_Ellipsis: {
  2002. Token op = f->curr_token;
  2003. next_token(f);
  2004. AstNode *right = parse_expr(f, false);
  2005. expr = ast_interval_expr(f, op, expr, right);
  2006. } break;
  2007. }
  2008. AstNodeArray rhs = {0};
  2009. array_init_count(&rhs, heap_allocator(), 1);
  2010. rhs.e[0] = expr;
  2011. return ast_assign_stmt(f, token, lhs, rhs);
  2012. }
  2013. break;
  2014. case Token_Colon:
  2015. return parse_value_decl(f, lhs);
  2016. }
  2017. if (lhs.count > 1) {
  2018. syntax_error(token, "Expected 1 expression");
  2019. return ast_bad_stmt(f, token, f->curr_token);
  2020. }
  2021. switch (token.kind) {
  2022. case Token_Inc:
  2023. case Token_Dec:
  2024. next_token(f);
  2025. return ast_inc_dec_stmt(f, token, lhs.e[0]);
  2026. }
  2027. return ast_expr_stmt(f, lhs.e[0]);
  2028. }
  2029. AstNode *parse_block_stmt(AstFile *f, b32 is_when) {
  2030. if (!is_when && f->curr_proc == NULL) {
  2031. syntax_error(f->curr_token, "You cannot use a block statement in the file scope");
  2032. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2033. }
  2034. return parse_body(f);
  2035. }
  2036. AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow);
  2037. AstNode *parse_results(AstFile *f) {
  2038. if (!allow_token(f, Token_ArrowRight)) {
  2039. return NULL;
  2040. }
  2041. if (f->curr_token.kind != Token_OpenParen) {
  2042. Token begin_token = f->curr_token;
  2043. AstNodeArray empty_names = {0};
  2044. AstNodeArray list = make_ast_node_array(f);
  2045. AstNode *type = parse_type(f);
  2046. array_add(&list, ast_field(f, empty_names, type, 0));
  2047. return ast_field_list(f, begin_token, list);
  2048. }
  2049. AstNode *list = NULL;
  2050. expect_token(f, Token_OpenParen);
  2051. list = parse_field_list(f, NULL, 0, Token_CloseParen);
  2052. expect_token_after(f, Token_CloseParen, "parameter list");
  2053. return list;
  2054. }
  2055. AstNode *parse_proc_type(AstFile *f, AstNode **foreign_library_, String *foreign_name_, String *link_name_) {
  2056. AstNode *params = {0};
  2057. AstNode *results = {0};
  2058. Token proc_token = expect_token(f, Token_proc);
  2059. expect_token(f, Token_OpenParen);
  2060. params = parse_field_list(f, NULL, FieldFlag_Signature, Token_CloseParen);
  2061. expect_token_after(f, Token_CloseParen, "parameter list");
  2062. results = parse_results(f);
  2063. u64 tags = 0;
  2064. String foreign_name = {0};
  2065. String link_name = {0};
  2066. AstNode *foreign_library = NULL;
  2067. ProcCallingConvention cc = ProcCC_Odin;
  2068. parse_proc_tags(f, &tags, &foreign_library, &foreign_name, &link_name, &cc);
  2069. if (foreign_library_) *foreign_library_ = foreign_library;
  2070. if (foreign_name_) *foreign_name_ = foreign_name;
  2071. if (link_name_) *link_name_ = link_name;
  2072. return ast_proc_type(f, proc_token, params, results, tags, cc);
  2073. }
  2074. AstNode *parse_var_type(AstFile *f, bool allow_ellipsis) {
  2075. if (allow_ellipsis && f->curr_token.kind == Token_Ellipsis) {
  2076. Token tok = f->curr_token;
  2077. next_token(f);
  2078. AstNode *type = parse_type_or_ident(f);
  2079. if (type == NULL) {
  2080. error(tok, "variadic field missing type after `...`");
  2081. type = ast_bad_expr(f, tok, f->curr_token);
  2082. }
  2083. return ast_ellipsis(f, tok, type);
  2084. }
  2085. AstNode *type = parse_type_attempt(f);
  2086. if (type == NULL) {
  2087. Token tok = f->curr_token;
  2088. error(tok, "Expected a type");
  2089. type = ast_bad_expr(f, tok, f->curr_token);
  2090. }
  2091. return type;
  2092. }
  2093. bool is_token_field_prefix(TokenKind kind) {
  2094. switch (kind) {
  2095. case Token_using:
  2096. case Token_no_alias:
  2097. case Token_immutable:
  2098. return true;
  2099. }
  2100. return false;
  2101. }
  2102. u32 parse_field_prefixes(AstFile *f) {
  2103. i32 using_count = 0;
  2104. i32 no_alias_count = 0;
  2105. i32 immutable_count = 0;
  2106. while (is_token_field_prefix(f->curr_token.kind)) {
  2107. switch (f->curr_token.kind) {
  2108. case Token_using: using_count += 1; next_token(f); break;
  2109. case Token_no_alias: no_alias_count += 1; next_token(f); break;
  2110. case Token_immutable: immutable_count += 1; next_token(f); break;
  2111. }
  2112. }
  2113. if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list");
  2114. if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple `no_alias` in this field list");
  2115. if (immutable_count > 1) syntax_error(f->curr_token, "Multiple `immutable` in this field list");
  2116. u32 field_flags = 0;
  2117. if (using_count > 0) field_flags |= FieldFlag_using;
  2118. if (no_alias_count > 0) field_flags |= FieldFlag_no_alias;
  2119. if (immutable_count > 0) field_flags |= FieldFlag_immutable;
  2120. return field_flags;
  2121. }
  2122. u32 check_field_prefixes(AstFile *f, isize name_count, u32 allowed_flags, u32 set_flags) {
  2123. if (name_count > 1 && (set_flags&FieldFlag_using)) {
  2124. syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
  2125. set_flags &= ~FieldFlag_using;
  2126. }
  2127. if ((allowed_flags&FieldFlag_using) == 0 && (set_flags&FieldFlag_using)) {
  2128. syntax_error(f->curr_token, "`using` is not allowed within this field list");
  2129. set_flags &= ~FieldFlag_using;
  2130. }
  2131. if ((allowed_flags&FieldFlag_no_alias) == 0 && (set_flags&FieldFlag_no_alias)) {
  2132. syntax_error(f->curr_token, "`no_alias` is not allowed within this field list");
  2133. set_flags &= ~FieldFlag_no_alias;
  2134. }
  2135. if ((allowed_flags&FieldFlag_immutable) == 0 && (set_flags&FieldFlag_immutable)) {
  2136. syntax_error(f->curr_token, "`immutable` is not allowed within this field list");
  2137. set_flags &= ~FieldFlag_immutable;
  2138. }
  2139. return set_flags;
  2140. }
  2141. typedef struct AstNodeAndFlags {
  2142. AstNode *node;
  2143. u32 flags;
  2144. } AstNodeAndFlags;
  2145. typedef Array(AstNodeAndFlags) AstNodeAndFlagsArray;
  2146. AstNodeArray convert_to_ident_list(AstFile *f, AstNodeAndFlagsArray list, bool ignore_flags) {
  2147. AstNodeArray idents = {0};
  2148. array_init_reserve(&idents, heap_allocator(), list.count);
  2149. // Convert to ident list
  2150. for_array(i, list) {
  2151. AstNode *ident = list.e[i].node;
  2152. if (!ignore_flags) {
  2153. if (i != 0) {
  2154. error_node(ident, "Illegal use of prefixes in parameter list");
  2155. }
  2156. }
  2157. switch (ident->kind) {
  2158. case AstNode_Ident:
  2159. case AstNode_BadExpr:
  2160. break;
  2161. default:
  2162. error_node(ident, "Expected an identifier");
  2163. ident = ast_ident(f, blank_token);
  2164. break;
  2165. }
  2166. array_add(&idents, ident);
  2167. }
  2168. return idents;
  2169. }
  2170. bool parse_expect_field_separator(AstFile *f, AstNode *param) {
  2171. Token token = f->curr_token;
  2172. if (allow_token(f, Token_Comma)) {
  2173. return true;
  2174. }
  2175. if (token.kind == Token_Semicolon) {
  2176. next_token(f);
  2177. error(f->curr_token, "Expected a comma, got a semicolon");
  2178. return true;
  2179. }
  2180. return false;
  2181. }
  2182. AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow) {
  2183. TokenKind separator = Token_Comma;
  2184. Token start_token = f->curr_token;
  2185. AstNodeArray params = make_ast_node_array(f);
  2186. AstNodeAndFlagsArray list = {0}; array_init(&list, heap_allocator()); // LEAK(bill):
  2187. isize total_name_count = 0;
  2188. bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis;
  2189. while (f->curr_token.kind != follow &&
  2190. f->curr_token.kind != Token_Colon &&
  2191. f->curr_token.kind != Token_EOF) {
  2192. u32 flags = parse_field_prefixes(f);
  2193. AstNode *param = parse_var_type(f, allow_ellipsis);
  2194. AstNodeAndFlags naf = {param, flags};
  2195. array_add(&list, naf);
  2196. if (f->curr_token.kind != Token_Comma) {
  2197. break;
  2198. }
  2199. next_token(f);
  2200. }
  2201. if (f->curr_token.kind == Token_Colon) {
  2202. AstNodeArray names = convert_to_ident_list(f, list, true); // Copy for semantic reasons
  2203. if (names.count == 0) {
  2204. syntax_error(f->curr_token, "Empty field declaration");
  2205. }
  2206. u32 set_flags = 0;
  2207. if (list.count > 0) {
  2208. set_flags = list.e[0].flags;
  2209. }
  2210. set_flags = check_field_prefixes(f, names.count, allowed_flags, set_flags);
  2211. total_name_count += names.count;
  2212. expect_token_after(f, Token_Colon, "field list");
  2213. AstNode *type = parse_var_type(f, allow_ellipsis);
  2214. AstNode *param = ast_field(f, names, type, set_flags);
  2215. array_add(&params, param);
  2216. parse_expect_field_separator(f, type);
  2217. while (f->curr_token.kind != follow &&
  2218. f->curr_token.kind != Token_EOF) {
  2219. u32 set_flags = parse_field_prefixes(f);
  2220. AstNodeArray names = parse_ident_list(f);
  2221. if (names.count == 0) {
  2222. syntax_error(f->curr_token, "Empty field declaration");
  2223. break;
  2224. }
  2225. set_flags = check_field_prefixes(f, names.count, allowed_flags, set_flags);
  2226. total_name_count += names.count;
  2227. expect_token_after(f, Token_Colon, "field list");
  2228. AstNode *type = parse_var_type(f, allow_ellipsis);
  2229. AstNode *param = ast_field(f, names, type, set_flags);
  2230. array_add(&params, param);
  2231. if (!parse_expect_field_separator(f, param)) {
  2232. break;
  2233. }
  2234. }
  2235. if (name_count_) *name_count_ = total_name_count;
  2236. return ast_field_list(f, start_token, params);
  2237. }
  2238. for_array(i, list) {
  2239. AstNodeArray names = {0};
  2240. AstNode *type = list.e[i].node;
  2241. Token token = blank_token;
  2242. array_init_count(&names, heap_allocator(), 1);
  2243. token.pos = ast_node_token(type).pos;
  2244. names.e[0] = ast_ident(f, token);
  2245. u32 flags = check_field_prefixes(f, list.count, allowed_flags, list.e[i].flags);
  2246. AstNode *param = ast_field(f, names, list.e[i].node, flags);
  2247. array_add(&params, param);
  2248. }
  2249. if (name_count_) *name_count_ = total_name_count;
  2250. return ast_field_list(f, start_token, params);
  2251. }
  2252. AstNode *parse_record_fields(AstFile *f, isize *field_count_, u32 flags, String context) {
  2253. return parse_field_list(f, field_count_, flags, Token_CloseBrace);
  2254. }
  2255. AstNode *parse_type_or_ident(AstFile *f) {
  2256. switch (f->curr_token.kind) {
  2257. case Token_Ident:
  2258. {
  2259. AstNode *e = parse_ident(f);
  2260. while (f->curr_token.kind == Token_Period) {
  2261. Token token = f->curr_token;
  2262. next_token(f);
  2263. AstNode *sel = parse_ident(f);
  2264. e = ast_selector_expr(f, token, e, sel);
  2265. }
  2266. if (f->curr_token.kind == Token_OpenParen) {
  2267. // HACK NOTE(bill): For type_of_val(expr) et al.
  2268. e = parse_call_expr(f, e);
  2269. }
  2270. return e;
  2271. }
  2272. case Token_Hash: {
  2273. Token hash_token = expect_token(f, Token_Hash);
  2274. Token name = expect_token(f, Token_Ident);
  2275. String tag = name.string;
  2276. if (str_eq(tag, str_lit("type"))) {
  2277. AstNode *type = parse_type(f);
  2278. return ast_helper_type(f, hash_token, type);
  2279. }
  2280. syntax_error(name, "Expected `type` after #");
  2281. return ast_bad_expr(f, hash_token, f->curr_token);
  2282. }
  2283. case Token_Pointer: {
  2284. Token token = expect_token(f, Token_Pointer);
  2285. AstNode *elem = parse_type(f);
  2286. return ast_pointer_type(f, token, elem);
  2287. }
  2288. case Token_OpenBracket: {
  2289. Token token = expect_token(f, Token_OpenBracket);
  2290. AstNode *count_expr = NULL;
  2291. bool is_vector = false;
  2292. if (f->curr_token.kind == Token_Ellipsis) {
  2293. count_expr = ast_unary_expr(f, expect_token(f, Token_Ellipsis), NULL);
  2294. } else if (f->curr_token.kind == Token_vector) {
  2295. next_token(f);
  2296. if (f->curr_token.kind != Token_CloseBracket) {
  2297. f->expr_level++;
  2298. count_expr = parse_expr(f, false);
  2299. f->expr_level--;
  2300. } else {
  2301. syntax_error(f->curr_token, "Vector type missing count");
  2302. }
  2303. is_vector = true;
  2304. } else if (f->curr_token.kind == Token_dynamic) {
  2305. next_token(f);
  2306. expect_token(f, Token_CloseBracket);
  2307. return ast_dynamic_array_type(f, token, parse_type(f));
  2308. } else if (f->curr_token.kind != Token_CloseBracket) {
  2309. f->expr_level++;
  2310. count_expr = parse_expr(f, false);
  2311. f->expr_level--;
  2312. }
  2313. expect_token(f, Token_CloseBracket);
  2314. if (is_vector) {
  2315. return ast_vector_type(f, token, count_expr, parse_type(f));
  2316. }
  2317. return ast_array_type(f, token, count_expr, parse_type(f));
  2318. }
  2319. case Token_map: {
  2320. Token token = expect_token(f, Token_map);
  2321. AstNode *count = NULL;
  2322. AstNode *key = NULL;
  2323. AstNode *value = NULL;
  2324. Token open = expect_token_after(f, Token_OpenBracket, "map");
  2325. key = parse_expr(f, true);
  2326. if (allow_token(f, Token_Comma)) {
  2327. count = key;
  2328. key = parse_type(f);
  2329. }
  2330. Token close = expect_token(f, Token_CloseBracket);
  2331. value = parse_type(f);
  2332. return ast_map_type(f, token, count, key, value);
  2333. } break;
  2334. case Token_struct: {
  2335. Token token = expect_token(f, Token_struct);
  2336. bool is_packed = false;
  2337. bool is_ordered = false;
  2338. AstNode *align = NULL;
  2339. isize prev_level = f->expr_level;
  2340. f->expr_level = -1;
  2341. while (allow_token(f, Token_Hash)) {
  2342. Token tag = expect_token_after(f, Token_Ident, "#");
  2343. if (str_eq(tag.string, str_lit("packed"))) {
  2344. if (is_packed) {
  2345. syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
  2346. }
  2347. is_packed = true;
  2348. } else if (str_eq(tag.string, str_lit("ordered"))) {
  2349. if (is_ordered) {
  2350. syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
  2351. }
  2352. is_ordered = true;
  2353. } else if (str_eq(tag.string, str_lit("align"))) {
  2354. if (align) {
  2355. syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
  2356. }
  2357. align = parse_expr(f, true);
  2358. } else {
  2359. syntax_error(tag, "Invalid struct tag `#%.*s`", LIT(tag.string));
  2360. }
  2361. }
  2362. f->expr_level = prev_level;
  2363. if (is_packed && is_ordered) {
  2364. syntax_error(token, "`#ordered` is not needed with `#packed` which implies ordering");
  2365. }
  2366. Token open = expect_token_after(f, Token_OpenBrace, "struct");
  2367. isize decl_count = 0;
  2368. AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("struct"));
  2369. Token close = expect_token(f, Token_CloseBrace);
  2370. AstNodeArray decls = {0};
  2371. if (fields != NULL) {
  2372. GB_ASSERT(fields->kind == AstNode_FieldList);
  2373. decls = fields->FieldList.list;
  2374. }
  2375. return ast_struct_type(f, token, decls, decl_count, is_packed, is_ordered, align);
  2376. } break;
  2377. case Token_union: {
  2378. Token token = expect_token(f, Token_union);
  2379. Token open = expect_token_after(f, Token_OpenBrace, "union");
  2380. AstNodeArray decls = make_ast_node_array(f);
  2381. AstNodeArray variants = make_ast_node_array(f);
  2382. isize total_decl_name_count = 0;
  2383. while (f->curr_token.kind != Token_CloseBrace &&
  2384. f->curr_token.kind != Token_EOF) {
  2385. u32 decl_flags = parse_field_prefixes(f);
  2386. if (decl_flags != 0) {
  2387. AstNodeArray names = parse_ident_list(f);
  2388. if (names.count == 0) {
  2389. syntax_error(f->curr_token, "Empty field declaration");
  2390. }
  2391. u32 set_flags = check_field_prefixes(f, names.count, FieldFlag_using, decl_flags);
  2392. total_decl_name_count += names.count;
  2393. expect_token_after(f, Token_Colon, "field list");
  2394. AstNode *type = parse_var_type(f, false);
  2395. array_add(&decls, ast_field(f, names, type, set_flags));
  2396. } else {
  2397. AstNodeArray names = parse_ident_list(f);
  2398. if (names.count == 0) {
  2399. break;
  2400. }
  2401. if (names.count > 1 || f->curr_token.kind == Token_Colon) {
  2402. u32 set_flags = check_field_prefixes(f, names.count, FieldFlag_using, decl_flags);
  2403. total_decl_name_count += names.count;
  2404. expect_token_after(f, Token_Colon, "field list");
  2405. AstNode *type = parse_var_type(f, false);
  2406. array_add(&decls, ast_field(f, names, type, set_flags));
  2407. } else {
  2408. AstNode *name = names.e[0];
  2409. Token open = expect_token(f, Token_OpenBrace);
  2410. isize decl_count = 0;
  2411. AstNode *list = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("union"));
  2412. Token close = expect_token(f, Token_CloseBrace);
  2413. array_add(&variants, ast_union_field(f, name, list));
  2414. }
  2415. }
  2416. if (f->curr_token.kind != Token_Comma) {
  2417. break;
  2418. }
  2419. next_token(f);
  2420. }
  2421. Token close = expect_token(f, Token_CloseBrace);
  2422. return ast_union_type(f, token, decls, total_decl_name_count, variants);
  2423. }
  2424. case Token_raw_union: {
  2425. Token token = expect_token(f, Token_raw_union);
  2426. Token open = expect_token_after(f, Token_OpenBrace, "raw_union");
  2427. isize decl_count = 0;
  2428. AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("raw_union"));
  2429. Token close = expect_token(f, Token_CloseBrace);
  2430. AstNodeArray decls = {0};
  2431. if (fields != NULL) {
  2432. GB_ASSERT(fields->kind == AstNode_FieldList);
  2433. decls = fields->FieldList.list;
  2434. }
  2435. return ast_raw_union_type(f, token, decls, decl_count);
  2436. }
  2437. case Token_enum: {
  2438. Token token = expect_token(f, Token_enum);
  2439. AstNode *base_type = NULL;
  2440. if (f->curr_token.kind != Token_OpenBrace) {
  2441. base_type = parse_type(f);
  2442. }
  2443. Token open = expect_token(f, Token_OpenBrace);
  2444. AstNodeArray values = parse_element_list(f);
  2445. Token close = expect_token(f, Token_CloseBrace);
  2446. return ast_enum_type(f, token, base_type, values);
  2447. }
  2448. case Token_proc: {
  2449. Token token = f->curr_token;
  2450. AstNode *pt = parse_proc_type(f, NULL, NULL, NULL);
  2451. if (pt->ProcType.tags != 0) {
  2452. syntax_error(token, "A procedure type cannot have tags");
  2453. }
  2454. return pt;
  2455. }
  2456. case Token_OpenParen: {
  2457. Token open = expect_token(f, Token_OpenParen);
  2458. AstNode *type = parse_type(f);
  2459. Token close = expect_token(f, Token_CloseParen);
  2460. return ast_paren_expr(f, type, open, close);
  2461. } break;
  2462. }
  2463. // No type found
  2464. return NULL;
  2465. }
  2466. AstNode *parse_body(AstFile *f) {
  2467. AstNodeArray stmts = {0};
  2468. Token open, close;
  2469. isize prev_expr_level = f->expr_level;
  2470. // NOTE(bill): The body may be within an expression so reset to zero
  2471. f->expr_level = 0;
  2472. open = expect_token(f, Token_OpenBrace);
  2473. stmts = parse_stmt_list(f);
  2474. close = expect_token(f, Token_CloseBrace);
  2475. f->expr_level = prev_expr_level;
  2476. return ast_block_stmt(f, stmts, open, close);
  2477. }
  2478. AstNode *parse_if_stmt(AstFile *f) {
  2479. if (f->curr_proc == NULL) {
  2480. syntax_error(f->curr_token, "You cannot use an if statement in the file scope");
  2481. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2482. }
  2483. Token token = expect_token(f, Token_if);
  2484. AstNode *init = NULL;
  2485. AstNode *cond = NULL;
  2486. AstNode *body = NULL;
  2487. AstNode *else_stmt = NULL;
  2488. isize prev_level = f->expr_level;
  2489. f->expr_level = -1;
  2490. if (allow_token(f, Token_Semicolon)) {
  2491. cond = parse_expr(f, false);
  2492. } else {
  2493. init = parse_simple_stmt(f, false);
  2494. if (allow_token(f, Token_Semicolon)) {
  2495. cond = parse_expr(f, false);
  2496. } else {
  2497. cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
  2498. init = NULL;
  2499. }
  2500. }
  2501. f->expr_level = prev_level;
  2502. if (cond == NULL) {
  2503. syntax_error(f->curr_token, "Expected condition for if statement");
  2504. }
  2505. body = parse_block_stmt(f, false);
  2506. if (allow_token(f, Token_else)) {
  2507. switch (f->curr_token.kind) {
  2508. case Token_if:
  2509. else_stmt = parse_if_stmt(f);
  2510. break;
  2511. case Token_OpenBrace:
  2512. else_stmt = parse_block_stmt(f, false);
  2513. break;
  2514. default:
  2515. syntax_error(f->curr_token, "Expected if statement block statement");
  2516. else_stmt = ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
  2517. break;
  2518. }
  2519. }
  2520. return ast_if_stmt(f, token, init, cond, body, else_stmt);
  2521. }
  2522. AstNode *parse_when_stmt(AstFile *f) {
  2523. Token token = expect_token(f, Token_when);
  2524. AstNode *cond = NULL;
  2525. AstNode *body = NULL;
  2526. AstNode *else_stmt = NULL;
  2527. isize prev_level = f->expr_level;
  2528. f->expr_level = -1;
  2529. cond = parse_expr(f, false);
  2530. f->expr_level = prev_level;
  2531. if (cond == NULL) {
  2532. syntax_error(f->curr_token, "Expected condition for when statement");
  2533. }
  2534. body = parse_block_stmt(f, true);
  2535. if (allow_token(f, Token_else)) {
  2536. switch (f->curr_token.kind) {
  2537. case Token_when:
  2538. else_stmt = parse_when_stmt(f);
  2539. break;
  2540. case Token_OpenBrace:
  2541. else_stmt = parse_block_stmt(f, true);
  2542. break;
  2543. default:
  2544. syntax_error(f->curr_token, "Expected when statement block statement");
  2545. else_stmt = ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
  2546. break;
  2547. }
  2548. }
  2549. return ast_when_stmt(f, token, cond, body, else_stmt);
  2550. }
  2551. AstNode *parse_return_stmt(AstFile *f) {
  2552. if (f->curr_proc == NULL) {
  2553. syntax_error(f->curr_token, "You cannot use a return statement in the file scope");
  2554. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2555. }
  2556. if (f->expr_level > 0) {
  2557. syntax_error(f->curr_token, "You cannot use a return statement within an expression");
  2558. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2559. }
  2560. Token token = expect_token(f, Token_return);
  2561. AstNodeArray results;
  2562. if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) {
  2563. results = parse_rhs_expr_list(f);
  2564. } else {
  2565. results = make_ast_node_array(f);
  2566. }
  2567. expect_semicolon(f, results.e[0]);
  2568. return ast_return_stmt(f, token, results);
  2569. }
  2570. // AstNode *parse_give_stmt(AstFile *f) {
  2571. // if (f->curr_proc == NULL) {
  2572. // syntax_error(f->curr_token, "You cannot use a give statement in the file scope");
  2573. // return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2574. // }
  2575. // if (f->expr_level == 0) {
  2576. // syntax_error(f->curr_token, "A give statement must be used within an expression");
  2577. // return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2578. // }
  2579. // Token token = expect_token(f, Token_give);
  2580. // AstNodeArray results;
  2581. // if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) {
  2582. // results = parse_rhs_expr_list(f);
  2583. // } else {
  2584. // results = make_ast_node_array(f);
  2585. // }
  2586. // AstNode *ge = ast_give_expr(f, token, results);
  2587. // expect_semicolon(f, ge);
  2588. // return ast_expr_stmt(f, ge);
  2589. // }
  2590. AstNode *parse_for_stmt(AstFile *f) {
  2591. if (f->curr_proc == NULL) {
  2592. syntax_error(f->curr_token, "You cannot use a for statement in the file scope");
  2593. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2594. }
  2595. Token token = expect_token(f, Token_for);
  2596. AstNode *init = NULL;
  2597. AstNode *cond = NULL;
  2598. AstNode *post = NULL;
  2599. AstNode *body = NULL;
  2600. bool is_range = false;
  2601. if (f->curr_token.kind != Token_OpenBrace) {
  2602. isize prev_level = f->expr_level;
  2603. f->expr_level = -1;
  2604. if (f->curr_token.kind != Token_Semicolon) {
  2605. cond = parse_simple_stmt(f, true);
  2606. if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
  2607. is_range = true;
  2608. }
  2609. }
  2610. if (!is_range && f->curr_token.kind == Token_Semicolon) {
  2611. next_token(f);
  2612. init = cond;
  2613. cond = NULL;
  2614. if (f->curr_token.kind != Token_Semicolon) {
  2615. cond = parse_simple_stmt(f, false);
  2616. }
  2617. expect_semicolon(f, cond);
  2618. if (f->curr_token.kind != Token_OpenBrace) {
  2619. post = parse_simple_stmt(f, false);
  2620. }
  2621. }
  2622. f->expr_level = prev_level;
  2623. }
  2624. body = parse_block_stmt(f, false);
  2625. if (is_range) {
  2626. GB_ASSERT(cond->kind == AstNode_AssignStmt);
  2627. Token in_token = cond->AssignStmt.op;
  2628. AstNode *value = NULL;
  2629. AstNode *index = NULL;
  2630. switch (cond->AssignStmt.lhs.count) {
  2631. case 1:
  2632. value = cond->AssignStmt.lhs.e[0];
  2633. break;
  2634. case 2:
  2635. value = cond->AssignStmt.lhs.e[0];
  2636. index = cond->AssignStmt.lhs.e[1];
  2637. break;
  2638. default:
  2639. error_node(cond, "Expected at 1 or 2 identifiers");
  2640. return ast_bad_stmt(f, token, f->curr_token);
  2641. }
  2642. AstNode *rhs = NULL;
  2643. if (cond->AssignStmt.rhs.count > 0) {
  2644. rhs = cond->AssignStmt.rhs.e[0];
  2645. }
  2646. return ast_range_stmt(f, token, value, index, in_token, rhs, body);
  2647. }
  2648. cond = convert_stmt_to_expr(f, cond, str_lit("boolean expression"));
  2649. return ast_for_stmt(f, token, init, cond, post, body);
  2650. }
  2651. AstNode *parse_case_clause(AstFile *f) {
  2652. Token token = f->curr_token;
  2653. AstNodeArray list = make_ast_node_array(f);
  2654. if (allow_token(f, Token_case)) {
  2655. list = parse_rhs_expr_list(f);
  2656. } else {
  2657. expect_token(f, Token_default);
  2658. }
  2659. expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
  2660. // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
  2661. AstNodeArray stmts = parse_stmt_list(f);
  2662. return ast_case_clause(f, token, list, stmts);
  2663. }
  2664. AstNode *parse_type_case_clause(AstFile *f) {
  2665. Token token = f->curr_token;
  2666. AstNodeArray list = make_ast_node_array(f);
  2667. if (allow_token(f, Token_case)) {
  2668. for (;;) {
  2669. AstNode *t = parse_type(f);
  2670. array_add(&list, t);
  2671. if (f->curr_token.kind != Token_Comma ||
  2672. f->curr_token.kind == Token_EOF) {
  2673. break;
  2674. }
  2675. next_token(f);
  2676. }
  2677. } else {
  2678. expect_token(f, Token_default);
  2679. }
  2680. expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
  2681. // expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
  2682. AstNodeArray stmts = parse_stmt_list(f);
  2683. return ast_case_clause(f, token, list, stmts);
  2684. }
  2685. AstNode *parse_match_stmt(AstFile *f) {
  2686. if (f->curr_proc == NULL) {
  2687. syntax_error(f->curr_token, "You cannot use a match statement in the file scope");
  2688. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2689. }
  2690. Token token = expect_token(f, Token_match);
  2691. AstNode *init = NULL;
  2692. AstNode *tag = NULL;
  2693. AstNode *body = NULL;
  2694. Token open, close;
  2695. bool is_type_match = false;
  2696. if (f->curr_token.kind != Token_OpenBrace) {
  2697. isize prev_level = f->expr_level;
  2698. f->expr_level = -1;
  2699. tag = parse_simple_stmt(f, true);
  2700. if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) {
  2701. is_type_match = true;
  2702. } else {
  2703. if (allow_token(f, Token_Semicolon)) {
  2704. init = tag;
  2705. tag = NULL;
  2706. if (f->curr_token.kind != Token_OpenBrace) {
  2707. tag = parse_simple_stmt(f, false);
  2708. }
  2709. }
  2710. }
  2711. f->expr_level = prev_level;
  2712. }
  2713. open = expect_token(f, Token_OpenBrace);
  2714. AstNodeArray list = make_ast_node_array(f);
  2715. while (f->curr_token.kind == Token_case ||
  2716. f->curr_token.kind == Token_default) {
  2717. if (is_type_match) {
  2718. array_add(&list, parse_type_case_clause(f));
  2719. } else {
  2720. array_add(&list, parse_case_clause(f));
  2721. }
  2722. }
  2723. close = expect_token(f, Token_CloseBrace);
  2724. body = ast_block_stmt(f, list, open, close);
  2725. if (!is_type_match) {
  2726. tag = convert_stmt_to_expr(f, tag, str_lit("match expression"));
  2727. return ast_match_stmt(f, token, init, tag, body);
  2728. } else {
  2729. return ast_type_match_stmt(f, token, tag, body);
  2730. }
  2731. }
  2732. AstNode *parse_defer_stmt(AstFile *f) {
  2733. if (f->curr_proc == NULL) {
  2734. syntax_error(f->curr_token, "You cannot use a defer statement in the file scope");
  2735. return ast_bad_stmt(f, f->curr_token, f->curr_token);
  2736. }
  2737. Token token = expect_token(f, Token_defer);
  2738. AstNode *stmt = parse_stmt(f);
  2739. switch (stmt->kind) {
  2740. case AstNode_EmptyStmt:
  2741. syntax_error(token, "Empty statement after defer (e.g. `;`)");
  2742. break;
  2743. case AstNode_DeferStmt:
  2744. syntax_error(token, "You cannot defer a defer statement");
  2745. stmt = stmt->DeferStmt.stmt;
  2746. break;
  2747. case AstNode_ReturnStmt:
  2748. syntax_error(token, "You cannot a return statement");
  2749. break;
  2750. }
  2751. return ast_defer_stmt(f, token, stmt);
  2752. }
  2753. AstNode *parse_asm_stmt(AstFile *f) {
  2754. Token token = expect_token(f, Token_asm);
  2755. bool is_volatile = false;
  2756. Token open, close, code_string;
  2757. open = expect_token(f, Token_OpenBrace);
  2758. code_string = expect_token(f, Token_String);
  2759. AstNode *output_list = NULL;
  2760. AstNode *input_list = NULL;
  2761. AstNode *clobber_list = NULL;
  2762. isize output_count = 0;
  2763. isize input_count = 0;
  2764. isize clobber_count = 0;
  2765. // TODO(bill): Finish asm statement and determine syntax
  2766. // if (f->curr_token.kind != Token_CloseBrace) {
  2767. // expect_token(f, Token_Colon);
  2768. // }
  2769. close = expect_token(f, Token_CloseBrace);
  2770. return ast_asm_stmt(f, token, is_volatile, open, close, code_string,
  2771. output_list, input_list, clobber_list,
  2772. output_count, input_count, clobber_count);
  2773. }
  2774. AstNode *parse_stmt(AstFile *f) {
  2775. AstNode *s = NULL;
  2776. Token token = f->curr_token;
  2777. switch (token.kind) {
  2778. // Operands
  2779. case Token_context:
  2780. case Token_Ident:
  2781. case Token_Integer:
  2782. case Token_Float:
  2783. case Token_Imag:
  2784. case Token_Rune:
  2785. case Token_String:
  2786. case Token_OpenParen:
  2787. // Unary Operators
  2788. case Token_Add:
  2789. case Token_Sub:
  2790. case Token_Xor:
  2791. case Token_Not:
  2792. s = parse_simple_stmt(f, false);
  2793. expect_semicolon(f, s);
  2794. return s;
  2795. case Token_if: return parse_if_stmt(f);
  2796. case Token_when: return parse_when_stmt(f);
  2797. case Token_for: return parse_for_stmt(f);
  2798. case Token_match: return parse_match_stmt(f);
  2799. case Token_defer: return parse_defer_stmt(f);
  2800. case Token_asm: return parse_asm_stmt(f);
  2801. case Token_return: return parse_return_stmt(f);
  2802. // case Token_give: return parse_give_stmt(f);
  2803. case Token_break:
  2804. case Token_continue:
  2805. case Token_fallthrough: {
  2806. AstNode *label = NULL;
  2807. next_token(f);
  2808. if (token.kind != Token_fallthrough &&
  2809. f->curr_token.kind == Token_Ident) {
  2810. label = parse_ident(f);
  2811. }
  2812. s = ast_branch_stmt(f, token, label);
  2813. expect_semicolon(f, s);
  2814. return s;
  2815. }
  2816. case Token_using: {
  2817. // TODO(bill): Make using statements better
  2818. Token token = expect_token(f, Token_using);
  2819. AstNodeArray list = parse_lhs_expr_list(f);
  2820. if (list.count == 0) {
  2821. syntax_error(token, "Illegal use of `using` statement");
  2822. expect_semicolon(f, NULL);
  2823. return ast_bad_stmt(f, token, f->curr_token);
  2824. }
  2825. if (f->curr_token.kind != Token_Colon) {
  2826. expect_semicolon(f, list.e[list.count-1]);
  2827. return ast_using_stmt(f, token, list);
  2828. }
  2829. AstNode *decl = parse_simple_stmt(f, false);
  2830. expect_semicolon(f, decl);
  2831. if (decl->kind == AstNode_ValueDecl) {
  2832. if (!decl->ValueDecl.is_var) {
  2833. syntax_error(token, "`using` may not be applied to constant declarations");
  2834. return decl;
  2835. }
  2836. if (f->curr_proc == NULL) {
  2837. syntax_error(token, "`using` is not allowed at the file scope");
  2838. } else {
  2839. decl->ValueDecl.flags |= VarDeclFlag_using;
  2840. }
  2841. return decl;
  2842. }
  2843. syntax_error(token, "Illegal use of `using` statement");
  2844. return ast_bad_stmt(f, token, f->curr_token);
  2845. } break;
  2846. #if 1
  2847. case Token_immutable: {
  2848. Token token = expect_token(f, Token_immutable);
  2849. AstNode *node = parse_stmt(f);
  2850. if (node->kind == AstNode_ValueDecl) {
  2851. if (!node->ValueDecl.is_var) {
  2852. syntax_error(token, "`immutable` may not be applied to constant declarations");
  2853. } else {
  2854. node->ValueDecl.flags |= VarDeclFlag_immutable;
  2855. }
  2856. return node;
  2857. }
  2858. syntax_error(token, "`immutable` may only be applied to a variable declaration");
  2859. return ast_bad_stmt(f, token, f->curr_token);
  2860. } break;
  2861. #endif
  2862. case Token_push_allocator: {
  2863. next_token(f);
  2864. isize prev_level = f->expr_level;
  2865. f->expr_level = -1;
  2866. AstNode *expr = parse_expr(f, false);
  2867. f->expr_level = prev_level;
  2868. AstNode *body = parse_block_stmt(f, false);
  2869. return ast_push_allocator(f, token, expr, body);
  2870. } break;
  2871. case Token_push_context: {
  2872. next_token(f);
  2873. isize prev_level = f->expr_level;
  2874. f->expr_level = -1;
  2875. AstNode *expr = parse_expr(f, false);
  2876. f->expr_level = prev_level;
  2877. AstNode *body = parse_block_stmt(f, false);
  2878. return ast_push_context(f, token, expr, body);
  2879. } break;
  2880. case Token_Hash: {
  2881. AstNode *s = NULL;
  2882. Token hash_token = expect_token(f, Token_Hash);
  2883. Token name = expect_token(f, Token_Ident);
  2884. String tag = name.string;
  2885. if (str_eq(tag, str_lit("label"))) {
  2886. AstNode *name = parse_ident(f);
  2887. AstNode *label = ast_label_decl(f, token, name);
  2888. AstNode *stmt = parse_stmt(f);
  2889. #define _SET_LABEL(Kind_, label_) case GB_JOIN2(AstNode_, Kind_): (stmt->Kind_).label = label_; break
  2890. switch (stmt->kind) {
  2891. _SET_LABEL(ForStmt, label);
  2892. _SET_LABEL(RangeStmt, label);
  2893. _SET_LABEL(MatchStmt, label);
  2894. _SET_LABEL(TypeMatchStmt, label);
  2895. default:
  2896. syntax_error(token, "#label cannot only be applied to a loop or match statement");
  2897. break;
  2898. }
  2899. #undef _SET_LABEL
  2900. return stmt;
  2901. } else if (str_eq(tag, str_lit("import"))) {
  2902. AstNode *cond = NULL;
  2903. Token import_name = {0};
  2904. switch (f->curr_token.kind) {
  2905. case Token_Period:
  2906. import_name = f->curr_token;
  2907. import_name.kind = Token_Ident;
  2908. next_token(f);
  2909. break;
  2910. case Token_Ident:
  2911. import_name = f->curr_token;
  2912. next_token(f);
  2913. break;
  2914. default:
  2915. import_name.pos = f->curr_token.pos;
  2916. break;
  2917. }
  2918. if (str_eq(import_name.string, str_lit("_"))) {
  2919. syntax_error(import_name, "Illegal #import name: `_`");
  2920. }
  2921. Token file_path = expect_token_after(f, Token_String, "#import");
  2922. if (allow_token(f, Token_when)) {
  2923. cond = parse_expr(f, false);
  2924. }
  2925. AstNode *decl = NULL;
  2926. if (f->curr_proc != NULL) {
  2927. syntax_error(import_name, "You cannot use `#import` within a procedure. This must be done at the file scope");
  2928. decl = ast_bad_decl(f, import_name, file_path);
  2929. } else {
  2930. decl = ast_import_decl(f, hash_token, true, file_path, import_name, cond);
  2931. }
  2932. expect_semicolon(f, decl);
  2933. return decl;
  2934. } else if (str_eq(tag, str_lit("load"))) {
  2935. AstNode *cond = NULL;
  2936. Token file_path = expect_token_after(f, Token_String, "#load");
  2937. Token import_name = file_path;
  2938. import_name.string = str_lit(".");
  2939. if (allow_token(f, Token_when)) {
  2940. cond = parse_expr(f, false);
  2941. }
  2942. AstNode *decl = NULL;
  2943. if (f->curr_proc != NULL) {
  2944. syntax_error(import_name, "You cannot use `#load` within a procedure. This must be done at the file scope");
  2945. decl = ast_bad_decl(f, import_name, file_path);
  2946. } else {
  2947. decl = ast_import_decl(f, hash_token, false, file_path, import_name, cond);
  2948. }
  2949. expect_semicolon(f, decl);
  2950. return decl;
  2951. } else if (str_eq(tag, str_lit("shared_global_scope"))) {
  2952. if (f->curr_proc == NULL) {
  2953. f->is_global_scope = true;
  2954. s = ast_empty_stmt(f, f->curr_token);
  2955. } else {
  2956. syntax_error(token, "You cannot use #shared_global_scope within a procedure. This must be done at the file scope");
  2957. s = ast_bad_decl(f, token, f->curr_token);
  2958. }
  2959. expect_semicolon(f, s);
  2960. return s;
  2961. } else if (str_eq(tag, str_lit("foreign_system_library"))) {
  2962. AstNode *cond = NULL;
  2963. Token lib_name = {0};
  2964. switch (f->curr_token.kind) {
  2965. case Token_Ident:
  2966. lib_name = f->curr_token;
  2967. next_token(f);
  2968. break;
  2969. default:
  2970. lib_name.pos = f->curr_token.pos;
  2971. break;
  2972. }
  2973. if (str_eq(lib_name.string, str_lit("_"))) {
  2974. syntax_error(lib_name, "Illegal #foreign_library name: `_`");
  2975. }
  2976. Token file_path = expect_token(f, Token_String);
  2977. if (allow_token(f, Token_when)) {
  2978. cond = parse_expr(f, false);
  2979. }
  2980. if (f->curr_proc == NULL) {
  2981. s = ast_foreign_library(f, hash_token, file_path, lib_name, cond, true);
  2982. } else {
  2983. syntax_error(token, "You cannot use #foreign_system_library within a procedure. This must be done at the file scope");
  2984. s = ast_bad_decl(f, token, file_path);
  2985. }
  2986. expect_semicolon(f, s);
  2987. return s;
  2988. } else if (str_eq(tag, str_lit("foreign_library"))) {
  2989. AstNode *cond = NULL;
  2990. Token lib_name = {0};
  2991. switch (f->curr_token.kind) {
  2992. case Token_Ident:
  2993. lib_name = f->curr_token;
  2994. next_token(f);
  2995. break;
  2996. default:
  2997. lib_name.pos = f->curr_token.pos;
  2998. break;
  2999. }
  3000. if (str_eq(lib_name.string, str_lit("_"))) {
  3001. syntax_error(lib_name, "Illegal #foreign_library name: `_`");
  3002. }
  3003. Token file_path = expect_token(f, Token_String);
  3004. if (allow_token(f, Token_when)) {
  3005. cond = parse_expr(f, false);
  3006. }
  3007. if (f->curr_proc == NULL) {
  3008. s = ast_foreign_library(f, hash_token, file_path, lib_name, cond, false);
  3009. } else {
  3010. syntax_error(token, "You cannot use #foreign_library within a procedure. This must be done at the file scope");
  3011. s = ast_bad_decl(f, token, file_path);
  3012. }
  3013. expect_semicolon(f, s);
  3014. return s;
  3015. } else if (str_eq(tag, str_lit("thread_local"))) {
  3016. AstNode *s = parse_stmt(f);
  3017. if (s->kind == AstNode_ValueDecl) {
  3018. if (!s->ValueDecl.is_var) {
  3019. syntax_error(token, "`thread_local` may not be applied to constant declarations");
  3020. }
  3021. if (f->curr_proc != NULL) {
  3022. syntax_error(token, "`thread_local` is only allowed at the file scope");
  3023. } else {
  3024. s->ValueDecl.flags |= VarDeclFlag_thread_local;
  3025. }
  3026. return s;
  3027. }
  3028. syntax_error(token, "`thread_local` may only be applied to a variable declaration");
  3029. return ast_bad_stmt(f, token, f->curr_token);
  3030. } else if (str_eq(tag, str_lit("bounds_check"))) {
  3031. s = parse_stmt(f);
  3032. s->stmt_state_flags |= StmtStateFlag_bounds_check;
  3033. if ((s->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) {
  3034. syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
  3035. }
  3036. return s;
  3037. } else if (str_eq(tag, str_lit("no_bounds_check"))) {
  3038. s = parse_stmt(f);
  3039. s->stmt_state_flags |= StmtStateFlag_no_bounds_check;
  3040. if ((s->stmt_state_flags & StmtStateFlag_bounds_check) != 0) {
  3041. syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
  3042. }
  3043. return s;
  3044. }
  3045. if (str_eq(tag, str_lit("include"))) {
  3046. syntax_error(token, "#include is not a valid import declaration kind. Use #load instead");
  3047. s = ast_bad_stmt(f, token, f->curr_token);
  3048. } else {
  3049. syntax_error(token, "Unknown tag directive used: `%.*s`", LIT(tag));
  3050. s = ast_bad_stmt(f, token, f->curr_token);
  3051. }
  3052. fix_advance_to_next_stmt(f);
  3053. return s;
  3054. } break;
  3055. case Token_OpenBrace:
  3056. return parse_block_stmt(f, false);
  3057. case Token_Semicolon:
  3058. s = ast_empty_stmt(f, token);
  3059. next_token(f);
  3060. return s;
  3061. }
  3062. syntax_error(token,
  3063. "Expected a statement, got `%.*s`",
  3064. LIT(token_strings[token.kind]));
  3065. fix_advance_to_next_stmt(f);
  3066. return ast_bad_stmt(f, token, f->curr_token);
  3067. }
  3068. AstNodeArray parse_stmt_list(AstFile *f) {
  3069. AstNodeArray list = make_ast_node_array(f);
  3070. while (f->curr_token.kind != Token_case &&
  3071. f->curr_token.kind != Token_default &&
  3072. f->curr_token.kind != Token_CloseBrace &&
  3073. f->curr_token.kind != Token_EOF) {
  3074. AstNode *stmt = parse_stmt(f);
  3075. if (stmt && stmt->kind != AstNode_EmptyStmt) {
  3076. array_add(&list, stmt);
  3077. if (stmt->kind == AstNode_ExprStmt &&
  3078. stmt->ExprStmt.expr != NULL &&
  3079. stmt->ExprStmt.expr->kind == AstNode_ProcLit) {
  3080. syntax_error_node(stmt, "Procedure literal evaluated but not used");
  3081. }
  3082. }
  3083. }
  3084. return list;
  3085. }
  3086. ParseFileError init_ast_file(AstFile *f, String fullpath) {
  3087. fullpath = string_trim_whitespace(fullpath); // Just in case
  3088. if (!string_has_extension(fullpath, str_lit("odin"))) {
  3089. return ParseFile_WrongExtension;
  3090. }
  3091. TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
  3092. if (err == TokenizerInit_None) {
  3093. array_init(&f->tokens, heap_allocator());
  3094. {
  3095. for (;;) {
  3096. Token token = tokenizer_get_token(&f->tokenizer);
  3097. if (token.kind == Token_Invalid) {
  3098. return ParseFile_InvalidToken;
  3099. }
  3100. array_add(&f->tokens, token);
  3101. if (token.kind == Token_EOF) {
  3102. break;
  3103. }
  3104. }
  3105. }
  3106. f->curr_token_index = 0;
  3107. f->prev_token = f->tokens.e[f->curr_token_index];
  3108. f->curr_token = f->tokens.e[f->curr_token_index];
  3109. // NOTE(bill): Is this big enough or too small?
  3110. isize arena_size = gb_size_of(AstNode);
  3111. arena_size *= 2*f->tokens.count;
  3112. gb_arena_init_from_allocator(&f->arena, heap_allocator(), arena_size);
  3113. f->curr_proc = NULL;
  3114. return ParseFile_None;
  3115. }
  3116. switch (err) {
  3117. case TokenizerInit_NotExists:
  3118. return ParseFile_NotFound;
  3119. case TokenizerInit_Permission:
  3120. return ParseFile_Permission;
  3121. case TokenizerInit_Empty:
  3122. return ParseFile_EmptyFile;
  3123. }
  3124. return ParseFile_InvalidFile;
  3125. }
  3126. void destroy_ast_file(AstFile *f) {
  3127. gb_arena_free(&f->arena);
  3128. array_free(&f->tokens);
  3129. gb_free(heap_allocator(), f->tokenizer.fullpath.text);
  3130. destroy_tokenizer(&f->tokenizer);
  3131. }
  3132. bool init_parser(Parser *p) {
  3133. array_init(&p->files, heap_allocator());
  3134. array_init(&p->imports, heap_allocator());
  3135. gb_mutex_init(&p->mutex);
  3136. return true;
  3137. }
  3138. void destroy_parser(Parser *p) {
  3139. // TODO(bill): Fix memory leak
  3140. for_array(i, p->files) {
  3141. destroy_ast_file(&p->files.e[i]);
  3142. }
  3143. #if 0
  3144. for_array(i, p->imports) {
  3145. // gb_free(heap_allocator(), p->imports[i].text);
  3146. }
  3147. #endif
  3148. array_free(&p->files);
  3149. array_free(&p->imports);
  3150. gb_mutex_destroy(&p->mutex);
  3151. }
  3152. // NOTE(bill): Returns true if it's added
  3153. bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
  3154. gb_mutex_lock(&p->mutex);
  3155. path = string_trim_whitespace(path);
  3156. rel_path = string_trim_whitespace(rel_path);
  3157. for_array(i, p->imports) {
  3158. String import = p->imports.e[i].path;
  3159. if (str_eq(import, path)) {
  3160. return false;
  3161. }
  3162. }
  3163. ImportedFile item;
  3164. item.path = path;
  3165. item.rel_path = rel_path;
  3166. item.pos = pos;
  3167. array_add(&p->imports, item);
  3168. gb_mutex_unlock(&p->mutex);
  3169. return true;
  3170. }
  3171. gb_global Rune illegal_import_runes[] = {
  3172. '"', '\'', '`', ' ', '\t', '\r', '\n', '\v', '\f',
  3173. '\\', // NOTE(bill): Disallow windows style filepaths
  3174. '!', '$', '%', '^', '&', '*', '(', ')', '=', '+',
  3175. '[', ']', '{', '}',
  3176. ';', ':', '#',
  3177. '|', ',', '<', '>', '?',
  3178. };
  3179. bool is_import_path_valid(String path) {
  3180. if (path.len > 0) {
  3181. u8 *start = path.text;
  3182. u8 *end = path.text + path.len;
  3183. u8 *curr = start;
  3184. while (curr < end) {
  3185. isize width = 1;
  3186. Rune r = curr[0];
  3187. if (r >= 0x80) {
  3188. width = gb_utf8_decode(curr, end-curr, &r);
  3189. if (r == GB_RUNE_INVALID && width == 1) {
  3190. return false;
  3191. }
  3192. else if (r == GB_RUNE_BOM && curr-start > 0) {
  3193. return false;
  3194. }
  3195. }
  3196. for (isize i = 0; i < gb_count_of(illegal_import_runes); i++) {
  3197. if (r == illegal_import_runes[i]) {
  3198. return false;
  3199. }
  3200. }
  3201. curr += width;
  3202. }
  3203. return true;
  3204. }
  3205. return false;
  3206. }
  3207. void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray decls) {
  3208. for_array(i, decls) {
  3209. AstNode *node = decls.e[i];
  3210. if (!is_ast_node_decl(node) &&
  3211. node->kind != AstNode_BadStmt &&
  3212. node->kind != AstNode_EmptyStmt) {
  3213. // NOTE(bill): Sanity check
  3214. syntax_error_node(node, "Only declarations are allowed at file scope %.*s", LIT(ast_node_strings[node->kind]));
  3215. } else if (node->kind == AstNode_ImportDecl) {
  3216. ast_node(id, ImportDecl, node);
  3217. String file_str = id->relpath.string;
  3218. if (!is_import_path_valid(file_str)) {
  3219. if (id->is_import) {
  3220. syntax_error_node(node, "Invalid import path: `%.*s`", LIT(file_str));
  3221. } else {
  3222. syntax_error_node(node, "Invalid include path: `%.*s`", LIT(file_str));
  3223. }
  3224. // NOTE(bill): It's a naughty name
  3225. decls.e[i] = ast_bad_decl(f, id->relpath, id->relpath);
  3226. continue;
  3227. }
  3228. gbAllocator allocator = heap_allocator(); // TODO(bill): Change this allocator
  3229. String rel_path = get_fullpath_relative(allocator, base_dir, file_str);
  3230. String import_file = rel_path;
  3231. if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
  3232. String abs_path = get_fullpath_core(allocator, file_str);
  3233. if (gb_file_exists(cast(char *)abs_path.text)) {
  3234. import_file = abs_path;
  3235. }
  3236. }
  3237. id->fullpath = import_file;
  3238. try_add_import_path(p, import_file, file_str, ast_node_token(node).pos);
  3239. } else if (node->kind == AstNode_ForeignLibrary) {
  3240. AstNodeForeignLibrary *fl = &node->ForeignLibrary;
  3241. String file_str = fl->filepath.string;
  3242. if (!is_import_path_valid(file_str)) {
  3243. if (fl->is_system) {
  3244. syntax_error_node(node, "Invalid `foreign_system_library` path");
  3245. } else {
  3246. syntax_error_node(node, "Invalid `foreign_library` path");
  3247. }
  3248. // NOTE(bill): It's a naughty name
  3249. f->decls.e[i] = ast_bad_decl(f, fl->token, fl->token);
  3250. continue;
  3251. }
  3252. fl->base_dir = base_dir;
  3253. }
  3254. }
  3255. }
  3256. void parse_file(Parser *p, AstFile *f) {
  3257. String filepath = f->tokenizer.fullpath;
  3258. String base_dir = filepath;
  3259. for (isize i = filepath.len-1; i >= 0; i--) {
  3260. if (base_dir.text[i] == '\\' ||
  3261. base_dir.text[i] == '/') {
  3262. break;
  3263. }
  3264. base_dir.len--;
  3265. }
  3266. while (f->curr_token.kind == Token_Comment) {
  3267. next_token(f);
  3268. }
  3269. f->decls = parse_stmt_list(f);
  3270. parse_setup_file_decls(p, f, base_dir, f->decls);
  3271. }
  3272. ParseFileError parse_files(Parser *p, char *init_filename) {
  3273. char *fullpath_str = gb_path_get_full_name(heap_allocator(), init_filename);
  3274. String init_fullpath = make_string_c(fullpath_str);
  3275. TokenPos init_pos = {0};
  3276. ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
  3277. {
  3278. String s = get_fullpath_core(heap_allocator(), str_lit("_preload.odin"));
  3279. ImportedFile runtime_file = {s, s, init_pos};
  3280. array_add(&p->imports, runtime_file);
  3281. }
  3282. {
  3283. String s = get_fullpath_core(heap_allocator(), str_lit("_soft_numbers.odin"));
  3284. ImportedFile runtime_file = {s, s, init_pos};
  3285. array_add(&p->imports, runtime_file);
  3286. }
  3287. array_add(&p->imports, init_imported_file);
  3288. p->init_fullpath = init_fullpath;
  3289. for_array(i, p->imports) {
  3290. ImportedFile imported_file = p->imports.e[i];
  3291. String import_path = imported_file.path;
  3292. String import_rel_path = imported_file.rel_path;
  3293. TokenPos pos = imported_file.pos;
  3294. AstFile file = {0};
  3295. ParseFileError err = init_ast_file(&file, import_path);
  3296. if (err != ParseFile_None) {
  3297. if (err == ParseFile_EmptyFile) {
  3298. return ParseFile_None;
  3299. }
  3300. if (pos.line != 0) {
  3301. gb_printf_err("%.*s(%td:%td) ", LIT(pos.file), pos.line, pos.column);
  3302. }
  3303. gb_printf_err("Failed to parse file: %.*s\n\t", LIT(import_rel_path));
  3304. switch (err) {
  3305. case ParseFile_WrongExtension:
  3306. gb_printf_err("Invalid file extension: File must have the extension `.odin`");
  3307. break;
  3308. case ParseFile_InvalidFile:
  3309. gb_printf_err("Invalid file or cannot be found");
  3310. break;
  3311. case ParseFile_Permission:
  3312. gb_printf_err("File permissions problem");
  3313. break;
  3314. case ParseFile_NotFound:
  3315. gb_printf_err("File cannot be found (`%.*s`)", LIT(import_path));
  3316. break;
  3317. case ParseFile_InvalidToken:
  3318. gb_printf_err("Invalid token found in file");
  3319. break;
  3320. }
  3321. gb_printf_err("\n");
  3322. return err;
  3323. }
  3324. parse_file(p, &file);
  3325. {
  3326. gb_mutex_lock(&p->mutex);
  3327. file.id = p->files.count;
  3328. array_add(&p->files, file);
  3329. p->total_line_count += file.tokenizer.line_count;
  3330. gb_mutex_unlock(&p->mutex);
  3331. }
  3332. }
  3333. for_array(i, p->files) {
  3334. p->total_token_count += p->files.e[i].tokens.count;
  3335. }
  3336. return ParseFile_None;
  3337. }