Parser.pm 148 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654
  1. package Sidef::Parser {
  2. use utf8;
  3. use 5.016;
  4. use Sidef::Types::Bool::Bool;
  5. use List::Util qw(first);
  6. use Scalar::Util qw(refaddr);
  7. # our $REGMARK;
  8. sub new {
  9. my (undef, %opts) = @_;
  10. my %options = (
  11. line => 1,
  12. inc => [],
  13. class => 'main', # a.k.a. namespace
  14. vars => {'main' => []},
  15. ref_vars_refs => {'main' => []},
  16. EOT => [],
  17. postfix_ops => { # postfix operators
  18. '--' => 1,
  19. '++' => 1,
  20. '...' => 1,
  21. '!' => 1,
  22. '!!' => 1,
  23. },
  24. hyper_ops => {
  25. # type => [takes args, method name]
  26. map => [1, 'map_operator'],
  27. pam => [1, 'pam_operator'],
  28. zip => [1, 'zip_operator'],
  29. wise => [1, 'wise_operator'],
  30. scalar => [1, 'scalar_operator'],
  31. rscalar => [1, 'rscalar_operator'],
  32. cross => [1, 'cross_operator'],
  33. unroll => [1, 'unroll_operator'],
  34. reduce => [0, 'reduce_operator'],
  35. lmap => [0, 'map_operator'],
  36. },
  37. static_obj_re => qr{\G
  38. (?:
  39. nil\b (?{ state $x = bless({}, 'Sidef::Types::Nil::Nil') })
  40. | null\b (?{ state $x = Sidef::Types::Null::Null->new })
  41. | true\b (?{ Sidef::Types::Bool::Bool::TRUE })
  42. | false\b (?{ Sidef::Types::Bool::Bool::FALSE })
  43. | next\b (?{ state $x = bless({}, 'Sidef::Types::Block::Next') })
  44. | break\b (?{ state $x = bless({}, 'Sidef::Types::Block::Break') })
  45. | Block\b (?{ state $x = bless({}, 'Sidef::DataTypes::Block::Block') })
  46. | Backtick\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::Backtick') })
  47. | ARGF\b (?{ state $x = bless({}, 'Sidef::Meta::Glob::ARGF') })
  48. | STDIN\b (?{ state $x = bless({}, 'Sidef::Meta::Glob::STDIN') })
  49. | STDOUT\b (?{ state $x = bless({}, 'Sidef::Meta::Glob::STDOUT') })
  50. | STDERR\b (?{ state $x = bless({}, 'Sidef::Meta::Glob::STDERR') })
  51. | Bool\b (?{ state $x = bless({}, 'Sidef::DataTypes::Bool::Bool') })
  52. | FileHandle\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::FileHandle') })
  53. | DirHandle\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::DirHandle') })
  54. | SocketHandle\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::SocketHandle') })
  55. | Dir\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::Dir') })
  56. | File\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::File') })
  57. | Arr(?:ay)?+\b (?{ state $x = bless({}, 'Sidef::DataTypes::Array::Array') })
  58. | Pair\b (?{ state $x = bless({}, 'Sidef::DataTypes::Array::Pair') })
  59. | Vec(?:tor)?\b (?{ state $x = bless({}, 'Sidef::DataTypes::Array::Vector') })
  60. | Matrix\b (?{ state $x = bless({}, 'Sidef::DataTypes::Array::Matrix') })
  61. | Hash\b (?{ state $x = bless({}, 'Sidef::DataTypes::Hash::Hash') })
  62. | Set\b (?{ state $x = bless({}, 'Sidef::DataTypes::Set::Set') })
  63. | Bag\b (?{ state $x = bless({}, 'Sidef::DataTypes::Set::Bag') })
  64. | Str(?:ing)?+\b (?{ state $x = bless({}, 'Sidef::DataTypes::String::String') })
  65. | Num(?:ber)?+\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Number') })
  66. | Mod\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Mod') })
  67. | Gauss\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Gauss') })
  68. | Quadratic\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Quadratic') })
  69. | Quaternion\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Quaternion') })
  70. | Poly(?:nomial)?\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Polynomial') })
  71. | Poly(?:nomial)?Mod\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::PolynomialMod') })
  72. | Frac(?:tion)?\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Fraction') })
  73. | Inf\b (?{ state $x = Sidef::Types::Number::Number->inf })
  74. | NaN\b (?{ state $x = Sidef::Types::Number::Number->nan })
  75. | Infi\b (?{ state $x = Sidef::Types::Number::Complex->new(0, Sidef::Types::Number::Number->inf) })
  76. | NaNi\b (?{ state $x = Sidef::Types::Number::Complex->new(0, Sidef::Types::Number::Number->nan) })
  77. | RangeNum(?:ber)?+\b (?{ state $x = bless({}, 'Sidef::DataTypes::Range::RangeNumber') })
  78. | RangeStr(?:ing)?+\b (?{ state $x = bless({}, 'Sidef::DataTypes::Range::RangeString') })
  79. | Range\b (?{ state $x = bless({}, 'Sidef::DataTypes::Range::Range') })
  80. | Socket\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::Socket') })
  81. | Pipe\b (?{ state $x = bless({}, 'Sidef::DataTypes::Glob::Pipe') })
  82. | Ref\b (?{ state $x = bless({}, 'Sidef::Variable::Ref') })
  83. | NamedParam\b (?{ state $x = bless({}, 'Sidef::DataTypes::Variable::NamedParam') })
  84. | Lazy\b (?{ state $x = bless({}, 'Sidef::DataTypes::Object::Lazy') })
  85. | LazyMethod\b (?{ state $x = bless({}, 'Sidef::DataTypes::Object::LazyMethod') })
  86. | Enumerator\b (?{ state $x = bless({}, 'Sidef::DataTypes::Object::Enumerator') })
  87. | Complex\b (?{ state $x = bless({}, 'Sidef::DataTypes::Number::Complex') })
  88. | Regexp?\b (?{ state $x = bless({}, 'Sidef::DataTypes::Regex::Regex') })
  89. | Object\b (?{ state $x = bless({}, 'Sidef::DataTypes::Object::Object') })
  90. | Sidef\b (?{ state $x = bless({}, 'Sidef::DataTypes::Sidef::Sidef') })
  91. | Sig\b (?{ state $x = bless({}, 'Sidef::Sys::Sig') })
  92. | Sys\b (?{ state $x = bless({}, 'Sidef::Sys::Sys') })
  93. | Perl\b (?{ state $x = bless({}, 'Sidef::DataTypes::Perl::Perl') })
  94. | Math\b (?{ state $x = bless({}, 'Sidef::Math::Math') })
  95. | Time\b (?{ state $x = Sidef::Time::Time->new })
  96. | Date\b (?{ state $x = Sidef::Time::Date->new })
  97. | \$\. (?{ state $x = bless({name => '$.'}, 'Sidef::Variable::Magic') })
  98. | \$\? (?{ state $x = bless({name => '$?'}, 'Sidef::Variable::Magic') })
  99. | \$\$ (?{ state $x = bless({name => '$$'}, 'Sidef::Variable::Magic') })
  100. | \$\^T\b (?{ state $x = bless({name => '$^T'}, 'Sidef::Variable::Magic') })
  101. | \$\| (?{ state $x = bless({name => '$|'}, 'Sidef::Variable::Magic') })
  102. | \$! (?{ state $x = bless({name => '$!'}, 'Sidef::Variable::Magic') })
  103. | \$" (?{ state $x = bless({name => '$"'}, 'Sidef::Variable::Magic') })
  104. | \$\\ (?{ state $x = bless({name => '$\\'}, 'Sidef::Variable::Magic') })
  105. | \$@ (?{ state $x = bless({name => '$@'}, 'Sidef::Variable::Magic') })
  106. | \$% (?{ state $x = bless({name => '$%'}, 'Sidef::Variable::Magic') })
  107. | \$~ (?{ state $x = bless({name => '$~'}, 'Sidef::Variable::Magic') })
  108. | \$/ (?{ state $x = bless({name => '$/'}, 'Sidef::Variable::Magic') })
  109. | \$& (?{ state $x = bless({name => '$&'}, 'Sidef::Variable::Magic') })
  110. | \$' (?{ state $x = bless({name => '$\''}, 'Sidef::Variable::Magic') })
  111. | \$` (?{ state $x = bless({name => '$`'}, 'Sidef::Variable::Magic') })
  112. | \$: (?{ state $x = bless({name => '$:'}, 'Sidef::Variable::Magic') })
  113. | \$\] (?{ state $x = bless({name => '$]'}, 'Sidef::Variable::Magic') })
  114. | \$\[ (?{ state $x = bless({name => '$['}, 'Sidef::Variable::Magic') })
  115. | \$; (?{ state $x = bless({name => '$;'}, 'Sidef::Variable::Magic') })
  116. | \$, (?{ state $x = bless({name => '$,'}, 'Sidef::Variable::Magic') })
  117. | \$\^O\b (?{ state $x = bless({name => '$^O'}, 'Sidef::Variable::Magic') })
  118. | \$\^PERL\b (?{ state $x = bless({name => '$^X', dump => '$^PERL'}, 'Sidef::Variable::Magic') })
  119. | (?:\$0|\$\^SIDEF)\b (?{ state $x = bless({name => '$0', dump => '$^SIDEF'}, 'Sidef::Variable::Magic') })
  120. | \$\) (?{ state $x = bless({name => '$)'}, 'Sidef::Variable::Magic') })
  121. | \$\( (?{ state $x = bless({name => '$('}, 'Sidef::Variable::Magic') })
  122. | \$< (?{ state $x = bless({name => '$<'}, 'Sidef::Variable::Magic') })
  123. | \$> (?{ state $x = bless({name => '$>'}, 'Sidef::Variable::Magic') })
  124. | ∞ (?{ state $x = Sidef::Types::Number::Number->inf })
  125. ) (?!::)
  126. }x,
  127. prefix_obj_re => qr{\G
  128. (?:
  129. if\b (?{ bless({}, 'Sidef::Types::Block::If') })
  130. | with\b (?{ bless({}, 'Sidef::Types::Block::With') })
  131. | while\b (?{ bless({}, 'Sidef::Types::Block::While') })
  132. | foreach\b (?{ bless({}, 'Sidef::Types::Block::ForEach') })
  133. | for\b (?{ bless({}, 'Sidef::Types::Block::For') })
  134. | return\b (?{ state $x = bless({}, 'Sidef::Types::Block::Return') })
  135. #| next\b (?{ bless({}, 'Sidef::Types::Block::Next') })
  136. #| break\b (?{ bless({}, 'Sidef::Types::Block::Break') })
  137. | read\b (?{ state $x = Sidef::Sys::Sys->new })
  138. | goto\b (?{ state $x = bless({}, 'Sidef::Perl::Builtin') })
  139. | (?:[*\\]|\+\+|--) (?{ state $x = bless({}, 'Sidef::Variable::Ref') })
  140. | (?:>>?|\@\|?|[√+~!\-\^]|
  141. (?:
  142. say
  143. | print
  144. | defined
  145. )\b) (?{ state $x = bless({}, 'Sidef::Operator::Unary') })
  146. | : (?{ state $x = bless({}, 'Sidef::Meta::PrefixColon') })
  147. )
  148. }x,
  149. quote_operators_re => qr{\G
  150. (?:
  151. # String
  152. (?: ['‘‚’] | %q\b. ) (?{ [qw(0 new Sidef::Types::String::String)] })
  153. |(?: ["“„”] | %(?:Q\b. | (?!\w). )) (?{ [qw(1 new Sidef::Types::String::String)] })
  154. # File
  155. | %f\b. (?{ [qw(0 new Sidef::Types::Glob::File)] })
  156. | %F\b. (?{ [qw(1 new Sidef::Types::Glob::File)] })
  157. # Dir
  158. | %d\b. (?{ [qw(0 new Sidef::Types::Glob::Dir)] })
  159. | %D\b. (?{ [qw(1 new Sidef::Types::Glob::Dir)] })
  160. # Pipe
  161. | %p\b. (?{ [qw(0 pipe Sidef::Types::Glob::Pipe)] })
  162. | %P\b. (?{ [qw(1 pipe Sidef::Types::Glob::Pipe)] })
  163. # Backtick
  164. | %x\b. (?{ [qw(0 new Sidef::Types::Glob::Backtick)] })
  165. | (?: %X\b. | ` ) (?{ [qw(1 new Sidef::Types::Glob::Backtick)] })
  166. # Bytes
  167. | %b\b. (?{ [qw(0 bytes Sidef::Types::Array::Array)] })
  168. | %B\b. (?{ [qw(1 bytes Sidef::Types::Array::Array)] })
  169. # Chars
  170. | %c\b. (?{ [qw(0 chars Sidef::Types::Array::Array)] })
  171. | %C\b. (?{ [qw(1 chars Sidef::Types::Array::Array)] })
  172. # Graphemes
  173. | %g\b. (?{ [qw(0 graphemes Sidef::Types::Array::Array)] })
  174. | %G\b. (?{ [qw(1 graphemes Sidef::Types::Array::Array)] })
  175. # Symbols
  176. | %[Os]\b. (?{ [qw(0 __NEW__ Sidef::Module::OO)] })
  177. | %S\b. (?{ [qw(0 __NEW__ Sidef::Module::Func)] })
  178. # Arbitrary Perl code
  179. | %perl\b. (?{ [qw(0 new Sidef::Types::Perl::Perl)] })
  180. | %Perl\b. (?{ [qw(1 new Sidef::Types::Perl::Perl)] })
  181. )
  182. }xs,
  183. built_in_classes => {
  184. map { $_ => 1 }
  185. qw(
  186. File
  187. FileHandle
  188. Dir
  189. DirHandle
  190. Arr Array
  191. Pair
  192. Vec Vector
  193. Matrix
  194. Enumerator
  195. Hash
  196. Set
  197. Bag
  198. Str String
  199. Num Number
  200. Poly Polynomial
  201. PolyMod PolynomialMod
  202. Frac Fraction
  203. Mod
  204. Gauss
  205. Quadratic
  206. Quaternion
  207. Range
  208. RangeStr RangeString
  209. RangeNum RangeNumber
  210. Complex
  211. Math
  212. Pipe
  213. Ref
  214. Socket
  215. SocketHandle
  216. Bool
  217. Sys
  218. Sig
  219. Regex Regexp
  220. Time
  221. Date
  222. Perl
  223. Sidef
  224. Object
  225. Parser
  226. Block
  227. Backtick
  228. Lazy
  229. LazyMethod
  230. NamedParam
  231. true false
  232. nil null
  233. )
  234. },
  235. keywords => {
  236. map { $_ => 1 }
  237. qw(
  238. next
  239. break
  240. return
  241. for foreach
  242. if elsif else
  243. with orwith
  244. while
  245. given
  246. with
  247. continue
  248. import
  249. include
  250. eval
  251. read
  252. die
  253. warn
  254. assert
  255. assert_eq
  256. assert_ne
  257. local
  258. global
  259. var
  260. del
  261. const
  262. func
  263. enum
  264. class
  265. static
  266. define
  267. struct
  268. subset
  269. module
  270. DATA
  271. ARGV
  272. ARGF
  273. ENV
  274. STDIN
  275. STDOUT
  276. STDERR
  277. __FILE__
  278. __LINE__
  279. __END__
  280. __DATA__
  281. __TIME__
  282. __DATE__
  283. __NAMESPACE__
  284. __COMPILED__
  285. __OPTIMIZED__
  286. )
  287. },
  288. match_flags_re => qr{[msixpogcaludn]+},
  289. var_name_re => qr/[^\W\d]\w*+(?>::[^\W\d]\w*)*/,
  290. method_name_re => qr/[^\W\d]\w*+!?/,
  291. var_init_sep_re => qr/\G\h*(?:=>|[=:])\h*/,
  292. operators_re => do {
  293. local $" = q{|};
  294. # Longest prefix first
  295. my @operators = map { quotemeta } qw(
  296. ||= ||
  297. &&= &&
  298. ^.. ..^
  299. %% ≅
  300. ~~ !~
  301. <~>
  302. <=> =~=
  303. <<= >>=
  304. << >>
  305. |>> |> |X> |Z>
  306. |= |
  307. &= &
  308. == =~
  309. := =
  310. <= >= < >
  311. ++ --
  312. += +
  313. -= -
  314. //= //
  315. /= / ÷= ÷
  316. **= **
  317. %= %
  318. ^= ^
  319. *= *
  320. ...
  321. != ..
  322. \\\\= \\\\
  323. !! !
  324. : : ⫶
  325. « » ~
  326. );
  327. qr{
  328. (?(DEFINE)
  329. (?<ops>
  330. @operators
  331. | \p{Block: Mathematical_Operators}
  332. | \p{Block: Supplemental_Mathematical_Operators}
  333. )
  334. )
  335. »(?<unroll>[^\W\d]\w*+|(?&ops))« # unroll operator (e.g.: »add« or »+«)
  336. | >>(?<unroll>[^\W\d]\w*+|(?&ops))<< # unroll operator (e.g.: >>add<< or >>+<<)
  337. | ~X(?<cross>[^\W\d]\w*+|(?&ops)|) # cross operator (e.g.: ~X or ~X+)
  338. | ~Z(?<zip>[^\W\d]\w*+|(?&ops)|) # zip operator (e.g.: ~Z or ~Z+)
  339. | ~W(?<wise>[^\W\d]\w*+|(?&ops)|) # wise operator (e.g.: ~W or ~W+)
  340. | ~S(?<scalar>[^\W\d]\w*+|(?&ops)|) # scalar operator (e.g.: ~S or ~S+)
  341. | ~RS(?<rscalar>[^\W\d]\w*+|(?&ops)|) # reverse scalar operator (e.g.: ~RS or ~RS/)
  342. | »(?<map>[^\W\d]\w*+|(?&ops))» # mapping operator (e.g.: »add» or »+»)
  343. | >>(?<map>[^\W\d]\w*+|(?&ops))>> # mapping operator (e.g.: >>add>> or >>+>>)
  344. | «(?<pam>[^\W\d]\w*+|(?&ops))« # reverse mapping operator (e.g.: «add« or «+«)
  345. | <<(?<pam>[^\W\d]\w*+|(?&ops))<< # reverse mapping operator (e.g.: <<add<< or <<+<<)
  346. | »(?<lmap>[^\W\d]\w*+|(?&ops))\(\)» # mapping operator (e.g.: »add()» or »+()»)
  347. | >>(?<lmap>[^\W\d]\w*+|(?&ops))\(\)>> # mapping operator (e.g.: >>add()>> or >>+()>>)
  348. | <<(?<reduce>[^\W\d]\w*+|(?&ops))>> # reduce operator (e.g.: <<add>> or <<+>>)
  349. | «(?<reduce>[^\W\d]\w*+|(?&ops))» # reduce operator (e.g.: «add» or «+»)
  350. | `(?<op>[^\W\d]\w*+!?)` # method-like operator (e.g.: `add` or `add!`)
  351. | (?<op>(?&ops)) # primitive operator (e.g.: +, -, *, /)
  352. }x;
  353. },
  354. # Reference: https://en.wikipedia.org/wiki/International_variation_in_quotation_marks
  355. delim_pairs => {
  356. qw~
  357. ( ) [ ] { } < >
  358. « » » « ‹ › › ‹
  359. „ ” “ ” ‘ ’ ‚ ’
  360. 〈 〉 ﴾ ﴿ 〈 〉 《 》
  361. 「 」 『 』 【 】 〔 〕
  362. 〖 〗 〘 〙 〚 〛 ⸨ ⸩
  363. ⌈ ⌉ ⌊ ⌋ 〈 〉 ❨ ❩
  364. ❪ ❫ ❬ ❭ ❮ ❯ ❰ ❱
  365. ❲ ❳ ❴ ❵ ⟅ ⟆ ⟦ ⟧
  366. ⟨ ⟩ ⟪ ⟫ ⟬ ⟭ ⟮ ⟯
  367. ⦃ ⦄ ⦅ ⦆ ⦇ ⦈ ⦉ ⦊
  368. ⦋ ⦌ ⦍ ⦎ ⦏ ⦐ ⦑ ⦒
  369. ⦗ ⦘ ⧘ ⧙ ⧚ ⧛ ⧼ ⧽
  370. ~
  371. },
  372. %opts,
  373. );
  374. $options{ref_vars} = $options{vars};
  375. $options{file_name} //= '-';
  376. $options{script_name} //= '-';
  377. bless \%options, __PACKAGE__;
  378. }
  379. sub fatal_error {
  380. my ($self, %opt) = @_;
  381. my $start = rindex($opt{code}, "\n", $opt{pos}) + 1;
  382. my $point = $opt{pos} - $start;
  383. my $line = $opt{line} // $self->{line};
  384. my $column = $point;
  385. my $error_line = (split(/\R/, substr($opt{code}, $start, $point + 80)))[0];
  386. if (length($error_line) > 80 && $point > 60) {
  387. my $from = $point - 40;
  388. my $rem = $point + 40 - length($error_line);
  389. $from -= $rem;
  390. $point = 40 + $rem;
  391. $error_line = substr($error_line, $from, 80);
  392. }
  393. my @lines = (
  394. "HAHA! That's really funny! You got me!",
  395. "I thought that... Oh, you got me!",
  396. "LOL! I expected... Oh, my! This is funny!",
  397. "Oh, oh... Wait a second! Did you mean...? Damn!",
  398. "You're embarrassing me! That's not funny!",
  399. "My brain just exploded.",
  400. "Sorry, I don't know how to help in this situation.",
  401. "I'm broken. Fix me, or show this to someone who can fix",
  402. "Huh?",
  403. "Out of order",
  404. "You must be joking.",
  405. "Ouch, That HURTS!",
  406. "Who are you!?",
  407. "Death before dishonour?",
  408. "Good afternoon, gentleman, I'm a HAL 9000 Computer",
  409. "Okie dokie, I'm dead",
  410. "Help is not available for you.",
  411. "Your expression has defeated me",
  412. "Your code has defeated me",
  413. "Your logic has defeated me",
  414. "Weird magic happens here",
  415. "I give up... dumping core now!",
  416. "Okie dokie, core dumped.bash",
  417. "You made me die. Shame on you!",
  418. "Invalid code. Feel ashamed for yourself and try again.",
  419. );
  420. my $error = sprintf("%s: %s\n\nFile : %s\nLine : %s : %s\nError: %s\n\n" . ("~" x 80) . "\n%s\n",
  421. 'sidef',
  422. $lines[rand @lines],
  423. $self->{file_name} // '-',
  424. $line, $column, join(', ', grep { defined } $opt{error}, $opt{reason}), $error_line);
  425. $error .= ' ' x ($point) . '^' . "\n" . ('~' x 80) . "\n";
  426. if (exists($opt{var})) {
  427. my ($name, $class) = $self->get_name_and_class($opt{var});
  428. my %seen;
  429. my @names;
  430. foreach my $var (@{$self->{vars}{$class}}) {
  431. next if ref $var eq 'ARRAY';
  432. if (!$seen{$var->{name}}++) {
  433. push @names, $var->{name};
  434. }
  435. }
  436. foreach my $var (@{$self->{ref_vars_refs}{$class}}) {
  437. next if ref $var eq 'ARRAY';
  438. if (!$seen{$var->{name}}++) {
  439. push @names, $var->{name};
  440. }
  441. }
  442. if ($class eq 'main') {
  443. $class = '';
  444. }
  445. else {
  446. $class .= '::';
  447. }
  448. if (my @candidates = Sidef::best_matches($name, [grep { $_ ne $name } @names])) {
  449. $error .= ("[?] Did you mean: " . join("\n" . (' ' x 18), map { $class . $_ } sort(@candidates)) . "\n");
  450. }
  451. }
  452. die $error;
  453. }
  454. sub find_var {
  455. my ($self, $var_name, $class) = @_;
  456. foreach my $var (@{$self->{vars}{$class}}) {
  457. next if ref $var eq 'ARRAY';
  458. if ($var->{name} eq $var_name) {
  459. return (wantarray ? ($var, 1) : $var);
  460. }
  461. }
  462. foreach my $var (@{$self->{ref_vars_refs}{$class}}) {
  463. next if ref $var eq 'ARRAY';
  464. if ($var->{name} eq $var_name) {
  465. return (wantarray ? ($var, 0) : $var);
  466. }
  467. }
  468. return;
  469. }
  470. sub check_declarations {
  471. my ($self, $hash_ref) = @_;
  472. foreach my $class (grep { $_ eq 'main' } keys %{$hash_ref}) {
  473. my $array_ref = $hash_ref->{$class};
  474. foreach my $variable (@{$array_ref}) {
  475. if (ref $variable eq 'ARRAY') {
  476. $self->check_declarations({$class => $variable});
  477. }
  478. elsif ($self->{interactive} or $self->{eval_mode}) {
  479. ## Everything is OK in interactive mode
  480. }
  481. elsif ( $variable->{count} == 0
  482. && $variable->{type} ne 'class'
  483. && $variable->{type} ne 'func'
  484. && $variable->{type} ne 'method'
  485. && $variable->{type} ne 'global'
  486. && $variable->{name} ne 'self'
  487. && $variable->{name} ne ''
  488. && $variable->{type} ne 'del'
  489. && chr(ord $variable->{name}) ne '_') {
  490. warn '[WARNING] '
  491. . "$variable->{type} '$variable->{name}' has been declared, but not used again at "
  492. . "$self->{file_name} line $variable->{line}\n";
  493. }
  494. }
  495. }
  496. }
  497. sub get_name_and_class {
  498. my ($self, $var_name) = @_;
  499. $var_name // return ('', $self->{class});
  500. my $rindex = rindex($var_name, '::');
  501. $rindex != -1
  502. ? (substr($var_name, $rindex + 2), substr($var_name, 0, $rindex))
  503. : ($var_name, $self->{class});
  504. }
  505. sub get_quoted_words {
  506. my ($self, %opt) = @_;
  507. my $string = $self->get_quoted_string(code => $opt{code}, no_count_line => 1);
  508. $self->parse_whitespace(code => \$string);
  509. my @words;
  510. while ($string =~ /\G((?>[^\s\\]+|\\.)++)/gcs) {
  511. push @words, $1 =~ s{\\#}{#}gr;
  512. $self->parse_whitespace(code => \$string);
  513. }
  514. return \@words;
  515. }
  516. sub get_quoted_string {
  517. my ($self, %opt) = @_;
  518. local *_ = $opt{code};
  519. /\G(?=\s)/ && $self->parse_whitespace(code => $opt{code});
  520. my $delim;
  521. if (/\G(?=(.))/) {
  522. $delim = $1;
  523. if ($delim eq '\\' && /\G\\(.*?)\\/gsc) {
  524. return $1;
  525. }
  526. }
  527. else {
  528. $self->fatal_error(
  529. error => qq{can't find the beginning of a string quote delimiter},
  530. code => $_,
  531. pos => pos($_),
  532. );
  533. }
  534. my $orig_pos = pos($_);
  535. my $beg_delim = quotemeta $delim;
  536. my $pair_delim = exists($self->{delim_pairs}{$delim}) ? $self->{delim_pairs}{$delim} : ();
  537. my $string = '';
  538. if (defined $pair_delim) {
  539. my $end_delim = quotemeta $pair_delim;
  540. my $re_delim = $beg_delim . $end_delim;
  541. # if (m{\G(?<main>$beg_delim((?>[^$re_delim\\]+|\\.|(?&main))*+)$end_delim)}sgc) {
  542. # if (m{\G(?<main>$beg_delim((?>[^\\$re_delim]*+(?>\\.[^\\$re_delim]*|(?&main)){0,}){0,})(?:$end_delim(*ACCEPT:term))?)(*PRUNE)(*FAIL)}sgc) {
  543. if (m{\G(?<main>$beg_delim((?>[^\\$re_delim]*+(?>\\.[^\\$re_delim]*|(?&main)){0,}){0,})$end_delim)}sgc) {
  544. $string = $2 =~ s/\\([$re_delim])/$1/gr;
  545. }
  546. }
  547. # elsif (m{\G$beg_delim([^\\$beg_delim]*+(?>\\.[^\\$beg_delim]*)*)}sgc) { # limited to 2^15-1 escapes
  548. # elsif (m{\G$beg_delim((?>(?>[^$beg_delim\\]++|\\.){0,}+){0,}+)}sgc) {
  549. # elsif (m{\G$beg_delim((?>[^\\$beg_delim]*+(?>\\.[^\\$beg_delim]*){0,}){0,})(?:$beg_delim(*ACCEPT:term))?(*PRUNE)(*FAIL)}sgc) {
  550. elsif (m{\G$beg_delim((?>[^\\$beg_delim]*+(?>\\.[^\\$beg_delim]*){0,}){0,})}sgc) {
  551. $string = $1 =~ s/\\([$beg_delim])/$1/gr;
  552. }
  553. # $REGMARK eq 'term'
  554. (defined($pair_delim) ? /\G(?<=\Q$pair_delim\E)/ : /\G$beg_delim/gc)
  555. || $self->fatal_error(
  556. error => sprintf(qq{can't find the quoted string terminator <<%s>>}, $pair_delim // $delim),
  557. code => $_,
  558. pos => $orig_pos,
  559. );
  560. $self->{line} += $string =~ s/\R\K//g if not $opt{no_count_line};
  561. return $string;
  562. }
  563. ## get_method_name() returns the following values:
  564. # 1st: method/operator (or undef)
  565. # 2nd: a true value if the operator requires an argument
  566. # 3rd: type of operator (defined in $self->{hyper_ops})
  567. sub get_method_name {
  568. my ($self, %opt) = @_;
  569. local *_ = $opt{code};
  570. # Parse whitespace
  571. $self->parse_whitespace(code => $opt{code});
  572. # Alpha-numeric method name
  573. if (/\G((?:SUPER::)*$self->{method_name_re})/goc) {
  574. return ($1, 0, '');
  575. }
  576. # Super-script power
  577. if (/\G(?=[⁰¹²³⁴⁵⁶⁷⁸⁹])/) {
  578. return ('**', 1, 'op');
  579. }
  580. # Operator-like method name
  581. if (m{\G$self->{operators_re}}goc) {
  582. my ($key) = keys(%+);
  583. return (
  584. $+,
  585. (
  586. exists($self->{hyper_ops}{$key})
  587. ? $self->{hyper_ops}{$key}[0]
  588. : not(exists $self->{postfix_ops}{$+})
  589. ),
  590. $key
  591. );
  592. }
  593. # Method name as expression
  594. my ($obj) = $self->parse_expr(code => $opt{code});
  595. return ({self => $obj // return}, 0, '');
  596. }
  597. sub parse_delim {
  598. my ($self, %opt) = @_;
  599. local *_ = $opt{code};
  600. my @delims = ('|', keys(%{$self->{delim_pairs}}));
  601. if (exists $opt{ignore_delim}) {
  602. @delims = grep { not exists $opt{ignore_delim}{$_} } @delims;
  603. }
  604. my $regex = do {
  605. local $" = "";
  606. qr/\G([@delims])\h*/;
  607. };
  608. my $end_delim;
  609. if (/$regex/gc) {
  610. $end_delim = $self->{delim_pairs}{$1} // $1;
  611. $self->parse_whitespace(code => $opt{code});
  612. }
  613. return $end_delim;
  614. }
  615. sub get_init_vars {
  616. my ($self, %opt) = @_;
  617. local *_ = $opt{code};
  618. my $end_delim = $self->parse_delim(%opt);
  619. my @vars;
  620. my %classes;
  621. while ( /\G(?<type>$self->{var_name_re}\h+$self->{var_name_re})\h*/goc
  622. || /\G([*:]?$self->{var_name_re})\h*/goc
  623. || (defined($end_delim) && /\G(?=[({])/)) {
  624. my $declaration = $1;
  625. if ($opt{with_vals} && defined($end_delim)) {
  626. # Add the variable into the symbol table
  627. if (defined $declaration) {
  628. my ($name, $class_name) = $self->get_name_and_class((split(' ', $declaration))[-1]);
  629. undef $classes{$class_name};
  630. unshift @{$self->{vars}{$class_name}},
  631. {
  632. obj => '',
  633. name => $name,
  634. count => 0,
  635. type => $opt{type},
  636. line => $self->{line},
  637. };
  638. }
  639. if (/\G<<?\h*/gc) {
  640. my ($var) = /\G($self->{var_name_re})\h*/goc;
  641. $var // $self->fatal_error(
  642. code => $_,
  643. pos => pos($_),
  644. error => 'expected a subset name',
  645. );
  646. $declaration .= " < $var ";
  647. }
  648. if (/\G(?=\{)/) {
  649. my $pos = pos($_);
  650. $self->parse_block(code => $opt{code}, topic_var => 1);
  651. $declaration .= substr($_, $pos, pos($_) - $pos);
  652. }
  653. elsif (/\G(?=\()/) {
  654. my $pos = pos($_);
  655. $self->parse_arg(code => $opt{code});
  656. $declaration .= substr($_, $pos, pos($_) - $pos);
  657. }
  658. if (/$self->{var_init_sep_re}/goc) {
  659. my $pos = pos($_);
  660. $self->parse_obj(code => $opt{code}, multiline => 1);
  661. $declaration .= '=' . substr($_, $pos, pos($_) - $pos);
  662. }
  663. }
  664. push @vars, $declaration;
  665. (defined($end_delim) && (/\G\h*,\h*/gc || /\G\h*(?:#.*)?+(?=\R)/gc)) || last;
  666. $self->parse_whitespace(code => $opt{code});
  667. }
  668. # Remove the newly added variables
  669. foreach my $class_name (keys %classes) {
  670. for (my $i = 0 ; $i <= $#{$self->{vars}{$class_name}} ; $i++) {
  671. if (ref($self->{vars}{$class_name}[$i]) eq 'HASH' and not ref($self->{vars}{$class_name}[$i]{obj})) {
  672. splice(@{$self->{vars}{$class_name}}, $i--, 1);
  673. }
  674. }
  675. }
  676. $self->parse_whitespace(code => $opt{code});
  677. defined($end_delim)
  678. && (
  679. /\G\h*\Q$end_delim\E/gc
  680. || $self->fatal_error(
  681. code => $_,
  682. pos => pos($_),
  683. error => "can't find the closing delimiter: `$end_delim`",
  684. )
  685. );
  686. return \@vars;
  687. }
  688. sub parse_init_vars {
  689. my ($self, %opt) = @_;
  690. local *_ = $opt{code};
  691. my $end_delim = $self->parse_delim(%opt);
  692. my @var_objs;
  693. while ( /\G(?<type>$self->{var_name_re})\h+($self->{var_name_re})\h*/goc
  694. || /\G([*:]?)($self->{var_name_re})\h*/goc
  695. || (defined($end_delim) && /\G(?=[({])/)) {
  696. my ($attr, $name) = ($1, $2);
  697. my $ref_type;
  698. if (defined($+{type})) {
  699. my $type = $+{type};
  700. my $obj = $self->parse_expr(code => \$type);
  701. if (not defined($obj) or ref($obj) eq 'HASH') {
  702. $self->fatal_error(
  703. code => $_,
  704. pos => pos($_),
  705. error => "invalid type <<$type>> for variable `$name`",
  706. reason => "expected a type, such as: Str, Num, File, etc...",
  707. );
  708. }
  709. $ref_type = $obj;
  710. }
  711. my ($subset);
  712. if (ref($ref_type) eq 'Sidef::Variable::Subset') {
  713. $subset = $ref_type;
  714. undef $ref_type;
  715. }
  716. my ($var_name, $class_name) = $self->get_name_and_class($name);
  717. if ($opt{type} eq 'del') {
  718. my $var = $self->find_var($var_name, $class_name);
  719. if (not defined($var)) {
  720. $self->fatal_error(
  721. code => $_,
  722. pos => pos($_) - length($name),
  723. var => ($class_name . '::' . $var_name),
  724. error => "attempt to delete non-existent variable `$name`",
  725. );
  726. }
  727. }
  728. if (exists($self->{keywords}{$var_name}) or exists($self->{built_in_classes}{$var_name})) {
  729. $self->fatal_error(
  730. code => $_,
  731. pos => $-[2],
  732. error => "`$var_name` is either a keyword or a predefined variable!",
  733. );
  734. }
  735. if (defined($end_delim) and m{\G<<?\h*}gc) {
  736. my ($subset_name) = /\G($self->{var_name_re})/goc;
  737. $subset_name // $self->fatal_error(
  738. code => $_,
  739. pos => pos($_),
  740. error => "expected the name of the subset",
  741. );
  742. my $code = $subset_name;
  743. my $obj = $self->parse_expr(code => \$code);
  744. (defined($obj) and ref($obj) ne 'HASH')
  745. || $self->fatal_error(
  746. code => $_,
  747. pos => pos($_),
  748. error => "expected a subset or a type",
  749. );
  750. $subset = $obj;
  751. }
  752. my ($value, $where_expr, $where_block);
  753. if (defined($end_delim)) {
  754. if (/\G\h*(?=\{)/gc) {
  755. $where_block = $self->parse_block(code => $opt{code}, topic_var => 1);
  756. }
  757. elsif (/\G\h*(?=\()/gc) {
  758. $where_expr = $self->parse_arg(code => $opt{code});
  759. }
  760. if (/$self->{var_init_sep_re}/goc) {
  761. my $obj = $self->parse_obj(code => $opt{code}, multiline => 1);
  762. $value = (
  763. ref($obj) eq 'HASH'
  764. ? $obj
  765. : {$self->{class} => [{self => $obj}]}
  766. );
  767. }
  768. }
  769. #<<<
  770. my $obj = bless(
  771. {
  772. name => $var_name,
  773. type => $opt{type},
  774. (defined($ref_type) ? (ref_type => $ref_type) : ()),
  775. (defined($subset) ? (subset => $subset) : ()),
  776. class => $class_name,
  777. defined($value) ? (value => $value, has_value => 1) : (),
  778. defined($attr)
  779. ? ($attr eq '*' ? (array => 1, slurpy => 1)
  780. : $attr eq ':' ? (hash => 1, slurpy => 1) : ())
  781. : (),
  782. defined($where_block) ? (where_block => $where_block) : (),
  783. defined($where_expr) ? (where_expr => $where_expr) : (),
  784. },
  785. 'Sidef::Variable::Variable'
  786. );
  787. #>>>
  788. if (exists($opt{callback})) {
  789. $opt{callback}->($obj);
  790. }
  791. if (!$opt{private} and $var_name ne '') {
  792. unshift @{$self->{vars}{$class_name}},
  793. {
  794. obj => $obj,
  795. name => $var_name,
  796. count => 0,
  797. type => $opt{type},
  798. line => $self->{line},
  799. };
  800. }
  801. if ($var_name eq '') {
  802. $obj->{name} = '__ANON__' . refaddr($obj);
  803. }
  804. push @var_objs, $obj;
  805. (defined($end_delim) && (/\G\h*,\h*/gc || /\G\h*(?:#.*)?+(?=\R)/gc)) || last;
  806. if ($opt{params} and $obj->{slurpy}) {
  807. $self->fatal_error(
  808. error => "can't declare more parameters after a slurpy parameter",
  809. code => $_,
  810. pos => pos($_),
  811. );
  812. }
  813. $self->parse_whitespace(code => $opt{code});
  814. }
  815. $self->parse_whitespace(code => $opt{code}) if defined($end_delim);
  816. defined($end_delim)
  817. && (
  818. /\G\h*\Q$end_delim\E/gc
  819. || $self->fatal_error(
  820. code => $_,
  821. pos => pos($_),
  822. error => "can't find the closing delimiter: `$end_delim`",
  823. )
  824. );
  825. return \@var_objs;
  826. }
  827. sub parse_whitespace {
  828. my ($self, %opt) = @_;
  829. my $beg_line = $self->{line};
  830. my $found_space = -1;
  831. local *_ = $opt{code};
  832. {
  833. ++$found_space;
  834. # Whitespace
  835. if (/\G(?=\s)/) {
  836. # Horizontal space
  837. if (/\G\h+/gc) {
  838. redo;
  839. }
  840. # Generic line
  841. if (/\G\R/gc) {
  842. ++$self->{line};
  843. # Here-document
  844. while ($#{$self->{EOT}} != -1) {
  845. my $eot = shift @{$self->{EOT}};
  846. my $name = $eot->{name};
  847. my $indent = $eot->{indent};
  848. my $spaces = 0;
  849. my $acc = '';
  850. until (/\G$name(?:\R|\z)/gc) {
  851. if (/\G(.*)/gc) {
  852. $acc .= "$1\n";
  853. }
  854. # Indentation is true
  855. if ($indent && /\G\R(\h*)$name(?:\R|\z)/gc) {
  856. $spaces = length($1);
  857. ++$self->{line};
  858. last;
  859. }
  860. /\G\R/gc
  861. ? ++$self->{line}
  862. : $self->fatal_error(
  863. error => "can't find string terminator <<$name>> anywhere before end-of-file",
  864. code => $_,
  865. pos => $eot->{pos},
  866. line => $eot->{line},
  867. );
  868. }
  869. if ($indent and $spaces > 0) {
  870. $acc =~ s/^\h{1,$spaces}//gm;
  871. }
  872. ++$self->{line};
  873. push @{$eot->{obj}{$self->{class}}},
  874. {
  875. self => (
  876. $eot->{type} == 0
  877. ? Sidef::Types::String::String->new($acc)
  878. : Sidef::Types::String::String->new($acc)->apply_escapes($self)
  879. )
  880. };
  881. }
  882. /\G\h+/gc;
  883. redo;
  884. }
  885. # Vertical space
  886. if (/\G\v+/gc) { # should not reach here
  887. redo;
  888. }
  889. }
  890. # ZERO WIDTH SPACE
  891. # https://www.fileformat.info/info/unicode/char/200b/index.htm
  892. if (/\G\x{200B}+/gc) {
  893. redo;
  894. }
  895. # Embedded comments (https://docs.raku.org/language/syntax#Multi-line_/_embedded_comments)
  896. if (/\G#`(?=[[:punct:]])/gc) {
  897. $self->get_quoted_string(code => $opt{code});
  898. redo;
  899. }
  900. # One-line comment
  901. if (/\G#.*/gc) {
  902. redo;
  903. }
  904. # Multi-line C comment
  905. if (m{\G/\*}gc) {
  906. while (1) {
  907. m{\G.*?\*/}gc && last;
  908. /\G.+/gc || (/\G\R/gc ? $self->{line}++ : last);
  909. }
  910. redo;
  911. }
  912. if ($found_space > 0) {
  913. return 1;
  914. }
  915. return;
  916. }
  917. }
  918. sub parse_expr {
  919. my ($self, %opt) = @_;
  920. local *_ = $opt{code};
  921. {
  922. $self->parse_whitespace(code => $opt{code});
  923. # End of an expression, or end of the script
  924. if (/\G;/gc || /\G\z/) {
  925. return;
  926. }
  927. if (/$self->{quote_operators_re}/goc) {
  928. my ($double_quoted, $method, $package) = @{$^R};
  929. pos($_) -= 1;
  930. my ($string, $pos) = $self->get_quoted_string(code => $opt{code});
  931. # Special case for array-like objects (bytes and chars)
  932. my @array_like;
  933. if ($method ne 'new' and $method ne '__NEW__') {
  934. @array_like = ($package, $method);
  935. $package = 'Sidef::Types::String::String';
  936. $method = 'new';
  937. }
  938. if ($package eq 'Sidef::Module::Func' or $package eq 'Sidef::Module::OO') {
  939. if ($string !~ /^$self->{var_name_re}\z/) {
  940. $self->fatal_error(
  941. code => $_,
  942. pos => (pos($_) - length($string) - 1),
  943. error => "invalid symbol declaration",
  944. reason => "expected a variable-like name",
  945. );
  946. }
  947. }
  948. my $obj = (
  949. $double_quoted
  950. ? do {
  951. state $str = Sidef::Types::String::String->new; # load the string module
  952. Sidef::Types::String::String::apply_escapes($package->$method($string), $self);
  953. }
  954. : $package->$method($string =~ s{\\\\}{\\}gr)
  955. );
  956. # Special case for backticks and Perl code (add method 'run')
  957. if ($package eq 'Sidef::Types::Glob::Backtick' or $package eq 'Sidef::Types::Perl::Perl') {
  958. my $struct =
  959. $double_quoted && ref($obj) eq 'HASH'
  960. ? $obj
  961. : {
  962. $self->{class} => [
  963. {
  964. self => $obj,
  965. call => [],
  966. }
  967. ]
  968. };
  969. push @{$struct->{$self->{class}}[-1]{call}}, {method => 'run'};
  970. $obj = $struct;
  971. }
  972. elsif (@array_like) {
  973. if ($double_quoted and ref($obj) eq 'HASH') {
  974. push @{$obj->{$self->{class}}[-1]{call}}, {method => $array_like[1]};
  975. }
  976. else {
  977. my $method = $array_like[1];
  978. $obj = $obj->$method;
  979. }
  980. }
  981. return $obj;
  982. }
  983. # Object as expression
  984. if (/\G(?=\()/) {
  985. my $obj = $self->parse_arg(code => $opt{code});
  986. return $obj;
  987. }
  988. # Block as object
  989. if (/\G(?=\{)/) {
  990. my $obj = $self->parse_block(code => $opt{code}, topic_var => 1);
  991. return $obj;
  992. }
  993. # Array as object
  994. if (/\G(?=\[)/) {
  995. my @array;
  996. my $obj = $self->parse_array(code => $opt{code});
  997. if (ref($obj->{$self->{class}}) eq 'ARRAY') {
  998. push @array, @{$obj->{$self->{class}}};
  999. }
  1000. return bless(\@array, 'Sidef::Types::Array::HCArray');
  1001. }
  1002. # Bareword followed by a fat comma or preceded by a colon
  1003. if ( /\G:(\w+)/gc
  1004. || /\G([^\W\d]\w*+)(?=\h*=>)/gc) {
  1005. # || /\G([^\W\d]\w*+)(?=\h*=>|:(?![=:]))/gc) {
  1006. return Sidef::Types::String::String->new($1);
  1007. }
  1008. # Bareword followed by a colon becomes a NamedParam with the bareword
  1009. # on the LHS
  1010. if (/\G([^\W\d]\w*+):(?![=:])/gc) {
  1011. my $name = $1;
  1012. my $obj = $self->parse_obj(code => $opt{code});
  1013. return Sidef::Variable::NamedParam->new($name, $obj);
  1014. }
  1015. # Declaration of variables (global and lexical)
  1016. if (/\G(var|global|del)\b\h*/gc) {
  1017. my $type = $1;
  1018. my $vars = $self->parse_init_vars(code => $opt{code}, type => $type);
  1019. my $init_obj = bless({vars => $vars}, 'Sidef::Variable::Init');
  1020. if (/\G\h*=\h*/gc) {
  1021. my $args = $self->parse_obj(code => $opt{code}, multiline => 1);
  1022. $args // $self->fatal_error(
  1023. code => $_,
  1024. pos => pos($_),
  1025. error => "expected an expression after variable declaration",
  1026. );
  1027. $init_obj->{args} = $args;
  1028. }
  1029. #if ($type eq 'del') {
  1030. # return bless {vars => []}, 'Sidef::Variable::Init';
  1031. #}
  1032. return $init_obj;
  1033. }
  1034. # "has" class attributes
  1035. if (exists($self->{current_class}) and /\Ghas\b\h*/gc) {
  1036. local $self->{allow_class_variable} = 0;
  1037. my $vars = $self->parse_init_vars(
  1038. code => $opt{code},
  1039. type => 'has',
  1040. private => 1,
  1041. );
  1042. foreach my $var (@{$vars}) {
  1043. my $name = $var->{name};
  1044. if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
  1045. $self->fatal_error(
  1046. code => $_,
  1047. pos => (pos($_) - length($name)),
  1048. error => "`$name` is either a keyword or a predefined variable!",
  1049. );
  1050. }
  1051. }
  1052. my $args;
  1053. if (/\G\h*=\h*/gc) {
  1054. $args = $self->parse_obj(code => $opt{code}, multiline => 1);
  1055. $args // $self->fatal_error(
  1056. code => $_,
  1057. pos => pos($_) - 2,
  1058. error => qq{expected an expression after "=" in `has` declaration},
  1059. );
  1060. }
  1061. my $obj = bless {vars => $vars, defined($args) ? (args => $args) : ()}, 'Sidef::Variable::ClassAttr';
  1062. push @{$self->{current_class}{attributes}}, $obj;
  1063. return $obj;
  1064. }
  1065. # Declaration of constants and static variables
  1066. if (/\G(define|const|static)\b\h*/gc) {
  1067. my $type = $1;
  1068. my $line = $self->{line};
  1069. my @var_objs;
  1070. my $callback = sub {
  1071. my ($v) = @_;
  1072. my $name = $v->{name};
  1073. my $class_name = $v->{class};
  1074. my $var = (
  1075. $type eq 'define' ? bless($v, 'Sidef::Variable::Define')
  1076. : $type eq 'static' ? bless($v, 'Sidef::Variable::Static')
  1077. : $type eq 'const' ? bless($v, 'Sidef::Variable::Const')
  1078. : die "[PARSER ERROR] Invalid variable type: $type"
  1079. );
  1080. push @var_objs, $var;
  1081. unshift @{$self->{vars}{$class_name}},
  1082. {
  1083. obj => $var,
  1084. name => $name,
  1085. count => 0,
  1086. type => $type,
  1087. line => $line,
  1088. };
  1089. };
  1090. my $vars = $self->parse_init_vars(
  1091. code => $opt{code},
  1092. type => $type,
  1093. private => 1,
  1094. callback => $callback,
  1095. );
  1096. foreach my $var (@var_objs) {
  1097. my $name = $var->{name};
  1098. if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
  1099. $self->fatal_error(
  1100. code => $_,
  1101. pos => (pos($_) - length($name)),
  1102. error => "`$name` is either a keyword or a predefined variable!",
  1103. );
  1104. }
  1105. }
  1106. if (@var_objs == 1 and /\G\h*=\h*/gc) {
  1107. my $var = $var_objs[0];
  1108. my $obj = $self->parse_obj(code => $opt{code}, multiline => 1);
  1109. $obj // $self->fatal_error(
  1110. code => $_,
  1111. pos => pos($_) - 2,
  1112. error => qq{expected an expression after $type "$var->{name}"},
  1113. );
  1114. $var->{value} = $obj;
  1115. }
  1116. my $const_init = bless({vars => \@var_objs, type => $type}, 'Sidef::Variable::ConstInit');
  1117. if (/\G\h*=\h*/gc) {
  1118. $self->fatal_error(
  1119. code => $_,
  1120. pos => pos($_) - 2,
  1121. error => qq{the correct syntax is: `$type(x = ..., y = ...)`},
  1122. );
  1123. }
  1124. return $const_init;
  1125. }
  1126. # Struct declaration
  1127. if (/\Gstruct\b\h*/gc) {
  1128. my ($name, $class_name);
  1129. if (/\G($self->{var_name_re})\h*/goc) {
  1130. ($name, $class_name) = $self->get_name_and_class($1);
  1131. }
  1132. if (defined($name) and (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name}))) {
  1133. $self->fatal_error(
  1134. code => $_,
  1135. pos => (pos($_) - length($name)),
  1136. error => "`$name` is either a keyword or a predefined variable!",
  1137. );
  1138. }
  1139. my $struct = bless(
  1140. {
  1141. name => $name,
  1142. class => $class_name,
  1143. },
  1144. 'Sidef::Variable::Struct'
  1145. );
  1146. if (defined $name) {
  1147. unshift @{$self->{vars}{$class_name}},
  1148. {
  1149. obj => $struct,
  1150. name => $name,
  1151. count => 0,
  1152. type => 'struct',
  1153. line => $self->{line},
  1154. };
  1155. }
  1156. my $vars =
  1157. $self->parse_init_vars(
  1158. code => $opt{code},
  1159. type => 'var',
  1160. private => 1,
  1161. );
  1162. $struct->{vars} = $vars;
  1163. return $struct;
  1164. }
  1165. # Subset declaration
  1166. if (/\Gsubset\b\h*/gc) {
  1167. my ($name, $class_name);
  1168. if (/\G($self->{var_name_re})\h*/goc) {
  1169. ($name, $class_name) = $self->get_name_and_class($1);
  1170. }
  1171. else {
  1172. $self->fatal_error(
  1173. code => $_,
  1174. pos => pos($_),
  1175. error => "expected a name after the keyword 'subset'",
  1176. );
  1177. }
  1178. if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
  1179. $self->fatal_error(
  1180. code => $_,
  1181. pos => (pos($_) - length($name)),
  1182. error => "`$name` is either a keyword or a predefined variable!",
  1183. );
  1184. }
  1185. my $subset = bless({name => $name, class => $class_name}, 'Sidef::Variable::Subset');
  1186. unshift @{$self->{vars}{$class_name}},
  1187. {
  1188. obj => $subset,
  1189. name => $name,
  1190. count => 0,
  1191. type => 'subset',
  1192. line => $self->{line},
  1193. };
  1194. # Inheritance
  1195. if (/\G<<?\h*/gc) {
  1196. {
  1197. my ($name) = /\G($self->{var_name_re})\h*/goc;
  1198. $name // $self->fatal_error(
  1199. code => $_,
  1200. pos => pos($_),
  1201. error => "expected a type name for subsetting",
  1202. );
  1203. my $code = $name;
  1204. my $type = $self->parse_expr(code => \$code);
  1205. push @{$subset->{inherits}}, $type;
  1206. /\G,\h*/gc && redo;
  1207. }
  1208. }
  1209. if (/\G(?=\{)/) {
  1210. my $block = $self->parse_block(code => $opt{code}, topic_var => 1);
  1211. $subset->{block} = $block;
  1212. }
  1213. return $subset;
  1214. }
  1215. # Declaration of enums
  1216. if (/\Genum\b\h*/gc) {
  1217. my $vars =
  1218. $self->parse_init_vars(
  1219. code => $opt{code},
  1220. type => 'var',
  1221. private => 1,
  1222. );
  1223. @{$vars}
  1224. || $self->fatal_error(
  1225. code => $_,
  1226. pos => pos($_),
  1227. error => q{expected one or more variable names after <enum>},
  1228. );
  1229. my $value = Sidef::Types::Number::Number::_set_int(-1);
  1230. foreach my $var (@{$vars}) {
  1231. my $name = $var->{name};
  1232. if (ref $var->{value} eq 'HASH') {
  1233. $var->{value} = $var->{value}{$self->{class}}[-1]{self};
  1234. }
  1235. $value =
  1236. $var->{has_value}
  1237. ? $var->{value}
  1238. : $value->inc;
  1239. if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
  1240. $self->fatal_error(
  1241. code => $_,
  1242. pos => (pos($_) - length($name)),
  1243. error => "`$name` is either a keyword or a predefined variable!",
  1244. );
  1245. }
  1246. unshift @{$self->{vars}{$self->{class}}},
  1247. {
  1248. obj => $value,
  1249. name => $name,
  1250. count => 0,
  1251. type => 'enum',
  1252. line => $self->{line},
  1253. };
  1254. }
  1255. return $value;
  1256. }
  1257. # Local variables
  1258. if (/\Glocal\b\h*/gc) {
  1259. my $expr = $self->parse_obj(code => $opt{code});
  1260. return bless({expr => $expr}, 'Sidef::Variable::Local');
  1261. }
  1262. # Declaration of classes, methods and functions
  1263. if (
  1264. /\G(func|class)\b\h*/gc
  1265. || /\G(->)\h*/gc
  1266. || (exists($self->{current_class})
  1267. && /\G(method)\b\h*/gc)
  1268. ) {
  1269. my $beg_pos = $-[0];
  1270. my $type =
  1271. $1 eq '->'
  1272. ? exists($self->{current_class}) && !(exists($self->{current_method}))
  1273. ? 'method'
  1274. : 'func'
  1275. : $1;
  1276. my $name = '';
  1277. my $class_name = $self->{class};
  1278. my $built_in_obj;
  1279. if ($type eq 'class' and /\G($self->{var_name_re})\h*/gco) {
  1280. $name = $1;
  1281. if (exists($self->{built_in_classes}{$name}) and /\G(?=[{<])/) {
  1282. my ($obj) = $self->parse_expr(code => \$name);
  1283. if (defined($obj)) {
  1284. $name = '';
  1285. $built_in_obj = $obj;
  1286. }
  1287. }
  1288. else {
  1289. ($name, $class_name) = $self->get_name_and_class($1);
  1290. }
  1291. }
  1292. if ($type eq 'method') {
  1293. $name = (
  1294. /\G($self->{method_name_re})\h*/goc ? $1
  1295. : /\G($self->{operators_re})\h*/goc ? $+
  1296. : ''
  1297. );
  1298. ($name, $class_name) = $self->get_name_and_class($name);
  1299. }
  1300. elsif ($type ne 'class') {
  1301. $name = /\G($self->{var_name_re})\h*/goc ? $1 : '';
  1302. ($name, $class_name) = $self->get_name_and_class($name);
  1303. }
  1304. if ( $type ne 'method'
  1305. and $type ne 'class'
  1306. and (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name}))) {
  1307. $self->fatal_error(
  1308. code => $_,
  1309. pos => $-[0],
  1310. error => "`$name` is either a keyword or a predefined variable!",
  1311. );
  1312. }
  1313. my $obj =
  1314. ($type eq 'func' or $type eq 'method') ? bless({name => $name, type => $type, class => $class_name}, 'Sidef::Variable::Variable')
  1315. : $type eq 'class' ? bless({name => ($built_in_obj // $name), class => $class_name}, 'Sidef::Variable::ClassInit')
  1316. : $self->fatal_error(
  1317. error => "invalid type",
  1318. reason => "expected a magic thing to happen",
  1319. code => $_,
  1320. pos => pos($_),
  1321. );
  1322. if ($name ne '') {
  1323. my $var = $self->find_var($name, $class_name);
  1324. if (defined($var) and $var->{type} eq 'class') {
  1325. $obj->{parent} = $var->{obj};
  1326. push @{$obj->{inherit}}, ref($var->{obj}{name}) ? $var->{obj}{name} : $var->{obj};
  1327. }
  1328. }
  1329. my $has_kids = 0;
  1330. my $parent;
  1331. if (($type eq 'method' or $type eq 'func') and $name ne '') {
  1332. my $var = $self->find_var($name, $class_name);
  1333. # A function or a method must be declared in the same scope
  1334. if (defined($var) and $var->{obj}{type} eq $type) {
  1335. $parent = $var->{obj};
  1336. $has_kids = 1;
  1337. #~ push @{$var->{obj}{value}{kids}}, $obj;
  1338. $parent->{has_kids} = 1;
  1339. $obj->{parent} = $parent;
  1340. }
  1341. }
  1342. if (not $has_kids) {
  1343. unshift @{$self->{vars}{$class_name}},
  1344. {
  1345. obj => $obj,
  1346. name => $name,
  1347. count => 0,
  1348. type => $type,
  1349. line => $self->{line},
  1350. };
  1351. }
  1352. if ($type eq 'class') {
  1353. my $var_names =
  1354. $self->parse_init_vars(
  1355. code => $opt{code},
  1356. params => 1,
  1357. private => 1,
  1358. type => 'has',
  1359. ignore_delim => {
  1360. '{' => 1,
  1361. '<' => 1,
  1362. },
  1363. );
  1364. # Set the class parameters
  1365. $obj->{vars} = $var_names;
  1366. # Class inheritance (class Name(...) << Name1, Name2)
  1367. if (/\G\h*<<?\h*/gc) {
  1368. while (/\G($self->{var_name_re})\h*/gco) {
  1369. my ($name, $class_name) = $self->get_name_and_class($1);
  1370. if (defined(my $class = $self->find_var($name, $class_name))) {
  1371. if ($class->{type} eq 'class') {
  1372. # Detect inheritance from the same class
  1373. if (refaddr($obj) == refaddr($class->{obj})) {
  1374. $self->fatal_error(
  1375. error => "Inheriting from the same class is not allowed",
  1376. code => $_,
  1377. pos => pos($_) - length($name) - 1,
  1378. );
  1379. }
  1380. ++$class->{count};
  1381. push @{$obj->{inherit}}, $class->{obj};
  1382. }
  1383. else {
  1384. $self->fatal_error(
  1385. error => "this is not a class",
  1386. reason => "expected a class name",
  1387. code => $_,
  1388. pos => pos($_) - length($name) - 1,
  1389. );
  1390. }
  1391. }
  1392. elsif (exists $self->{built_in_classes}{$name}) {
  1393. $self->fatal_error(
  1394. error => "Inheriting from built-in classes is not supported",
  1395. reason => "`$name` is a built-in class",
  1396. code => $_,
  1397. pos => pos($_) - length($name) - 1,
  1398. );
  1399. }
  1400. else {
  1401. $self->fatal_error(
  1402. error => "can't find `$name` class",
  1403. reason => "expected an existent class name",
  1404. var => ($class_name . '::' . $name),
  1405. code => $_,
  1406. pos => pos($_) - length($name) - 1,
  1407. );
  1408. }
  1409. /\G,\h*/gc;
  1410. }
  1411. }
  1412. /\G\h*(?=\{)/gc
  1413. || $self->fatal_error(
  1414. error => "invalid class declaration",
  1415. reason => "expected: class $name(...){...}",
  1416. code => $_,
  1417. pos => pos($_)
  1418. );
  1419. #~ if (ref($built_in_obj) eq 'Sidef::Variable::ClassInit') {
  1420. #~ $obj->{name} = $built_in_obj->{name};
  1421. #~ }
  1422. local $self->{class_name} = (defined($built_in_obj) ? ref($built_in_obj) : $obj->{name});
  1423. local $self->{current_class} = $built_in_obj // $obj;
  1424. my $block = $self->parse_block(code => $opt{code});
  1425. # Set the block of the class
  1426. $obj->{block} = $block;
  1427. }
  1428. if ($type eq 'func' or $type eq 'method') {
  1429. my $var_names = do {
  1430. local $self->{allow_class_variable} = 1 if $type eq 'method';
  1431. $self->get_init_vars(
  1432. code => $opt{code},
  1433. with_vals => 1,
  1434. ignore_delim => {
  1435. '{' => 1,
  1436. '-' => 1,
  1437. }
  1438. );
  1439. };
  1440. # Functions and method traits (example: "is cached")
  1441. if (/\G\h*is\h+(?=\w)/gc) {
  1442. while (/\G(\w+)/gc) {
  1443. my $trait = $1;
  1444. if ($trait eq 'cached') {
  1445. $obj->{cached} = 1;
  1446. }
  1447. #elsif ($type eq 'method' and $trait eq 'exported') {
  1448. # $obj->{exported} = 1;
  1449. #}
  1450. else {
  1451. $self->fatal_error(
  1452. error => "Unknown $type trait: $trait",
  1453. code => $_,
  1454. pos => pos($_),
  1455. );
  1456. }
  1457. /\G\h*,\h*/gc || last;
  1458. }
  1459. }
  1460. # Function return type (func name(...) -> Type {...})
  1461. if (/\G\h*->\h*/gc) {
  1462. my @ref;
  1463. if (/\G\(/gc) { # multiple types
  1464. while (1) {
  1465. my ($ref) = $self->parse_expr(code => $opt{code});
  1466. push @ref, $ref;
  1467. /\G\s*\)/gc && last;
  1468. /\G\s*,\s*/gc
  1469. || $self->fatal_error(
  1470. error => "invalid return-type for $type $self->{class_name}<<$name>>",
  1471. reason => "expected a comma",
  1472. code => $_,
  1473. pos => pos($_),
  1474. );
  1475. }
  1476. }
  1477. else { # only one type
  1478. my ($ref) = $self->parse_expr(code => $opt{code});
  1479. push @ref, $ref;
  1480. }
  1481. foreach my $ref (@ref) {
  1482. if (ref($ref) eq 'HASH') {
  1483. $self->fatal_error(
  1484. error => "invalid return-type for $type $self->{class_name}<<$name>>",
  1485. reason => "expected a valid type, such as: Str, Num, Arr, etc...",
  1486. code => $_,
  1487. pos => pos($_),
  1488. );
  1489. }
  1490. }
  1491. $obj->{returns} = \@ref;
  1492. }
  1493. /\G\h*\{\h*/gc
  1494. || $self->fatal_error(
  1495. error => "invalid `$type` declaration",
  1496. reason => "expected: $type $name(...){...}",
  1497. code => $_,
  1498. pos => pos($_)
  1499. );
  1500. local $self->{$type eq 'func' ? 'current_function' : 'current_method'} = $has_kids ? $parent : $obj;
  1501. my $args = '|' . join(',', $type eq 'method' ? 'self' : (), @{$var_names}) . ' |';
  1502. my $code = '{' . $args . substr($_, pos);
  1503. my $block = $self->parse_block(code => \$code, with_vars => 1);
  1504. pos($_) += pos($code) - length($args) - 1;
  1505. # Set the block of the function/method
  1506. $obj->{value} = $block;
  1507. }
  1508. return $obj;
  1509. }
  1510. # "given(expr) {...}" construct
  1511. if (/\Ggiven\b\h*/gc) {
  1512. my $expr = (
  1513. /\G(?=\()/
  1514. ? $self->parse_arg(code => $opt{code})
  1515. : $self->parse_obj(code => $opt{code})
  1516. );
  1517. $expr // $self->fatal_error(
  1518. error => "invalid declaration of the `given/when` construct",
  1519. reason => "expected `given(expr) {...}`",
  1520. code => $_,
  1521. pos => pos($_),
  1522. );
  1523. my $given_obj = bless({expr => $expr}, 'Sidef::Types::Block::Given');
  1524. local $self->{current_given} = $given_obj;
  1525. my $block = (
  1526. /\G\h*(?=\{)/gc
  1527. ? $self->parse_block(code => $opt{code}, topic_var => 1)
  1528. : $self->fatal_error(
  1529. error => "expected a block after `given(expr)`",
  1530. code => $_,
  1531. pos => pos($_),
  1532. )
  1533. );
  1534. $given_obj->{block} = $block;
  1535. return $given_obj;
  1536. }
  1537. # "when(expr) {...}" construct
  1538. if (exists($self->{current_given}) && /\Gwhen\b\h*/gc) {
  1539. my $expr = (
  1540. /\G(?=\()/
  1541. ? $self->parse_arg(code => $opt{code})
  1542. : $self->parse_obj(code => $opt{code})
  1543. );
  1544. $expr // $self->fatal_error(
  1545. error => "invalid declaration of the `when` construct",
  1546. reason => "expected `when(expr) {...}`",
  1547. code => $_,
  1548. pos => pos($_),
  1549. );
  1550. my $block = (
  1551. /\G\h*(?=\{)/gc
  1552. ? $self->parse_block(code => $opt{code}, with_vars => 1)
  1553. : $self->fatal_error(
  1554. error => "expected a block after `when(expr)`",
  1555. code => $_,
  1556. pos => pos($_),
  1557. )
  1558. );
  1559. return bless({expr => $expr, block => $block}, 'Sidef::Types::Block::When');
  1560. }
  1561. # "case(expr) {...}" construct
  1562. if (exists($self->{current_given}) && /\Gcase\b\h*/gc) {
  1563. my $expr = (
  1564. /\G(?=\()/
  1565. ? $self->parse_arg(code => $opt{code})
  1566. : $self->parse_obj(code => $opt{code})
  1567. );
  1568. $expr // $self->fatal_error(
  1569. error => "invalid declaration of the `case` construct",
  1570. reason => "expected `case(expr) {...}`",
  1571. code => $_,
  1572. pos => pos($_),
  1573. );
  1574. my $block = (
  1575. /\G\h*(?=\{)/gc
  1576. ? $self->parse_block(code => $opt{code}, with_vars => 1)
  1577. : $self->fatal_error(
  1578. error => "expected a block after `case(expr)`",
  1579. code => $_,
  1580. pos => pos($_),
  1581. )
  1582. );
  1583. return bless({expr => $expr, block => $block}, 'Sidef::Types::Block::Case');
  1584. }
  1585. # "default {...}" or "else { ... }" construct for `given/when`
  1586. if (exists($self->{current_given}) && /\G(?:default|else)\h*(?=\{)/gc) {
  1587. my $block = $self->parse_block(code => $opt{code});
  1588. return bless({block => $block}, 'Sidef::Types::Block::Default');
  1589. }
  1590. # `continue` keyword inside a given/when construct
  1591. if (exists($self->{current_given}) && /\Gcontinue\b/gc) {
  1592. state $x = bless({}, 'Sidef::Types::Block::Continue');
  1593. return $x;
  1594. }
  1595. # "do {...}" construct
  1596. if (/\Gdo\h*(?=\{)/gc) {
  1597. my $block = $self->parse_block(code => $opt{code});
  1598. return bless({block => $block}, 'Sidef::Types::Block::Do');
  1599. }
  1600. # "loop {...}" construct
  1601. if (/\Gloop\h*(?=\{)/gc) {
  1602. my $block = $self->parse_block(code => $opt{code});
  1603. return bless({block => $block}, 'Sidef::Types::Block::Loop');
  1604. }
  1605. # "try/catch" construct
  1606. if (/\Gtry\h*(?=\{)/gc) {
  1607. my $try_block = $self->parse_block(code => $opt{code});
  1608. my $obj = bless({try => $try_block}, 'Sidef::Types::Block::Try');
  1609. $self->parse_whitespace(code => $opt{code});
  1610. if (/\Gcatch\h*(?=\{)/gc) {
  1611. $obj->{catch} = $self->parse_block(code => $opt{code}, with_vars => 1);
  1612. }
  1613. else {
  1614. $self->backtrack_whitespace(code => $opt{code});
  1615. }
  1616. return $obj;
  1617. }
  1618. # "gather/take" construct
  1619. if (/\Ggather\h*(?=\{)/gc) {
  1620. my $obj = bless({}, 'Sidef::Types::Block::Gather');
  1621. local $self->{current_gather} = $obj;
  1622. my $block = $self->parse_block(code => $opt{code});
  1623. $obj->{block} = $block;
  1624. return $obj;
  1625. }
  1626. if (exists($self->{current_gather}) and /\Gtake\b\h*/gc) {
  1627. my $obj = (
  1628. /\G(?=\()/
  1629. ? $self->parse_arg(code => $opt{code})
  1630. : $self->parse_obj(code => $opt{code})
  1631. );
  1632. return bless({expr => $obj, gather => $self->{current_gather}}, 'Sidef::Types::Block::Take');
  1633. }
  1634. # Declaration of a module
  1635. if (/\Gmodule\b\h*/gc) {
  1636. my $name =
  1637. /\G($self->{var_name_re})\h*/goc
  1638. ? $1
  1639. : $self->fatal_error(
  1640. error => "invalid module declaration",
  1641. reason => "expected a name",
  1642. code => $_,
  1643. pos => pos($_)
  1644. );
  1645. $self->parse_whitespace(code => $opt{code});
  1646. if (/\G(?=\{)/) {
  1647. my $prev_class = $self->{class};
  1648. local $self->{class} = $name;
  1649. my $obj = $self->parse_block(code => $opt{code}, is_module => 1, prev_class => $prev_class);
  1650. return
  1651. bless {
  1652. name => $name,
  1653. block => $obj
  1654. },
  1655. 'Sidef::Meta::Module';
  1656. }
  1657. else {
  1658. $self->fatal_error(
  1659. error => "invalid module declaration",
  1660. reason => "expected: module $name {...}",
  1661. code => $_,
  1662. pos => pos($_)
  1663. );
  1664. }
  1665. }
  1666. if (/\Gimport\b\h*/gc) {
  1667. my $import_pos = pos($_);
  1668. my $var_names =
  1669. $self->get_init_vars(code => $opt{code},
  1670. with_vals => 0);
  1671. $self->backtrack_whitespace(code => $opt{code});
  1672. @{$var_names}
  1673. || $self->fatal_error(
  1674. code => $_,
  1675. pos => $import_pos,
  1676. error => "expected a variable-like name for importing!",
  1677. );
  1678. foreach my $var_name (@{$var_names}) {
  1679. my ($name, $class) = $self->get_name_and_class($var_name);
  1680. if ($class eq ($self->{class})) {
  1681. $self->fatal_error(
  1682. code => $_,
  1683. pos => $import_pos,
  1684. error => "can't import '${class}::${name}' into the same namespace",
  1685. );
  1686. }
  1687. my $var = $self->find_var($name, $class);
  1688. if (not defined $var) {
  1689. $self->fatal_error(
  1690. code => $_,
  1691. pos => $import_pos,
  1692. error => "variable '${class}::${name}' does not exists",
  1693. );
  1694. }
  1695. $var->{count}++;
  1696. unshift @{$self->{vars}{$self->{class}}},
  1697. {
  1698. obj => $var->{obj},
  1699. name => $name,
  1700. count => 0,
  1701. type => $var->{type},
  1702. line => $self->{line},
  1703. };
  1704. }
  1705. return 1;
  1706. }
  1707. if (/\Ginclude\b\h*/gc) {
  1708. my $include_pos = pos($_);
  1709. state $x = do {
  1710. require Cwd;
  1711. require File::Spec;
  1712. require File::Basename;
  1713. };
  1714. if (@{$self->{inc}} == 0) {
  1715. push @{$self->{inc}}, split(':', $ENV{SIDEF_INC}) if exists($ENV{SIDEF_INC});
  1716. push @{$self->{inc}}, File::Spec->catdir(File::Basename::dirname(Cwd::abs_path($0)), File::Spec->updir, 'share', 'sidef');
  1717. if (-f $self->{script_name}) {
  1718. push @{$self->{inc}}, File::Basename::dirname(Cwd::abs_path($self->{script_name}));
  1719. }
  1720. push @{$self->{inc}}, File::Spec->curdir;
  1721. }
  1722. my @abs_filenames;
  1723. if (/\G($self->{var_name_re})/gc) {
  1724. my $var_name = $1;
  1725. # The module is defined in the current file -- skip
  1726. if (exists $self->{ref_vars}{$var_name}) {
  1727. redo;
  1728. }
  1729. # The module was already included -- skip
  1730. if (exists $Sidef::INCLUDED{$var_name}) {
  1731. redo;
  1732. }
  1733. my @path = split(/::/, $var_name);
  1734. my $mod_path = File::Spec->catfile(@path[0 .. $#path - 1], $path[-1] . '.sm');
  1735. $Sidef::INCLUDED{$var_name} = $mod_path;
  1736. my ($full_path, $found_module);
  1737. foreach my $inc_dir (@{$self->{inc}}) {
  1738. if ( -e ($full_path = File::Spec->catfile($inc_dir, $mod_path))
  1739. and -f _
  1740. and -r _ ) {
  1741. $found_module = 1;
  1742. last;
  1743. }
  1744. }
  1745. $found_module // $self->fatal_error(
  1746. code => $_,
  1747. pos => $include_pos,
  1748. error => "can't find the module '${mod_path}' anywhere in ['" . join("', '", @{$self->{inc}}) . "']",
  1749. );
  1750. push @abs_filenames, [$full_path, $var_name];
  1751. }
  1752. else {
  1753. my $orig_dir = Cwd::getcwd();
  1754. my $orig_file = Cwd::abs_path($self->{file_name});
  1755. my $file_dir = File::Basename::dirname($orig_file);
  1756. my $chdired = 0;
  1757. if ($orig_dir ne $file_dir) {
  1758. if (chdir($file_dir)) {
  1759. $chdired = 1;
  1760. }
  1761. }
  1762. my $expr = do {
  1763. my ($obj) = $self->parse_expr(code => $opt{code});
  1764. $obj;
  1765. };
  1766. my @files = (
  1767. ref($expr) eq 'HASH'
  1768. ? do {
  1769. map { $_->{self} }
  1770. map { @{$_->{self}->{$self->{class}}} }
  1771. map { @{$expr->{$_}} }
  1772. keys %{$expr};
  1773. }
  1774. : $expr
  1775. );
  1776. push @abs_filenames, map {
  1777. my $filename = $_;
  1778. if (index(ref($filename), 'Sidef::') == 0) {
  1779. $filename = $filename->get_value;
  1780. }
  1781. ref($filename) ne ''
  1782. and $self->fatal_error(
  1783. code => ${$opt{code}},
  1784. pos => $include_pos,
  1785. error => 'include-error: invalid value of type "' . ref($filename) . '" (expected a string)',
  1786. );
  1787. my @files;
  1788. foreach my $file (glob($filename)) {
  1789. my $resolved = 0;
  1790. foreach my $base ('', @{$self->{inc}}) {
  1791. my $abs_path = File::Spec->rel2abs($file, $base) // next;
  1792. if (-f $abs_path) {
  1793. push @files, $abs_path;
  1794. $resolved = 1;
  1795. last;
  1796. }
  1797. }
  1798. if (!$resolved) {
  1799. $self->fatal_error(
  1800. code => ${$opt{code}},
  1801. pos => $include_pos,
  1802. error => "include-error: could not resolve path to file `$file`",
  1803. );
  1804. }
  1805. }
  1806. foreach my $file (@files) {
  1807. if (exists $Sidef::INCLUDED{$file}) {
  1808. $self->fatal_error(
  1809. code => ${$opt{code}},
  1810. pos => $include_pos,
  1811. error => "include-error: circular inclusion of file `$file`",
  1812. );
  1813. }
  1814. }
  1815. map { [$_] } @files
  1816. } @files;
  1817. if ($chdired) { chdir($orig_dir) }
  1818. }
  1819. my @included;
  1820. foreach my $pair (@abs_filenames) {
  1821. my ($full_path, $name) = @{$pair};
  1822. open(my $fh, '<:utf8', $full_path)
  1823. || $self->fatal_error(
  1824. code => ${$opt{code}},
  1825. pos => $include_pos,
  1826. error => "can't open file `$full_path`: $!"
  1827. );
  1828. my $content = do { local $/; <$fh> };
  1829. close $fh;
  1830. next if $Sidef::INCLUDED{$full_path};
  1831. local $self->{class} = $name if defined $name; # new namespace
  1832. local $self->{line} = 1;
  1833. local $self->{file_name} = $full_path;
  1834. local $Sidef::INCLUDED{$full_path} = 1;
  1835. my $ast = $self->parse_script(code => \$content);
  1836. push @included,
  1837. {
  1838. name => $name,
  1839. file => $full_path,
  1840. ast => $ast,
  1841. };
  1842. }
  1843. return bless({included => \@included}, 'Sidef::Meta::Included');
  1844. }
  1845. # Super-script power
  1846. if (/\G([⁰¹²³⁴⁵⁶⁷⁸⁹]+)/gc) {
  1847. my $num = ($1 =~ tr/⁰¹²³⁴⁵⁶⁷⁸⁹/0-9/r);
  1848. return Sidef::Types::Number::Number::_set_int($num);
  1849. }
  1850. # Binary, hexadecimal and octal numbers
  1851. if (/\G0(b[10_]*|x[0-9A-Fa-f_]*|o[0-7_]*|[0-7_]+)\b/gc) {
  1852. my $num = $1 =~ tr/_//dr;
  1853. return
  1854. Sidef::Types::Number::Number->new(
  1855. $num =~ /^b/ ? (substr($num, 1) || 0, 2)
  1856. : $num =~ /^o/ ? (substr($num, 1) || 0, 8)
  1857. : $num =~ /^x/ ? (substr($num, 1) || 0, 16)
  1858. : ($num || 0, 8)
  1859. );
  1860. }
  1861. # Integer or float number
  1862. if (/\G((?=\.?[0-9])[0-9_]*+(?:\.[0-9_]++)?(?:[Ee](?:[+-]?+[0-9_]+))?)/gc) {
  1863. my $num = $1 =~ tr/_//dr;
  1864. if (/\Gi\b/gc) { # imaginary
  1865. return Sidef::Types::Number::Complex->new(0, $num);
  1866. }
  1867. elsif (/\Gf\b/gc) { # floating-point
  1868. return Sidef::Types::Number::Number::_set_str('float', $num);
  1869. }
  1870. return (
  1871. $num =~ /^-?[0-9]+\z/
  1872. ? Sidef::Types::Number::Number::_set_int($num)
  1873. : Sidef::Types::Number::Number->new($num)
  1874. );
  1875. }
  1876. # Prefix `...`
  1877. if (/\G\.\.\./gc) {
  1878. return
  1879. bless(
  1880. {
  1881. line => $self->{line},
  1882. file => $self->{file_name},
  1883. },
  1884. 'Sidef::Meta::Unimplemented'
  1885. );
  1886. }
  1887. # Implicit method call on special variable: "_"
  1888. if (/\G\./) {
  1889. if (defined(my $var = $self->find_var('_', $self->{class}))) {
  1890. $var->{count}++;
  1891. return $var->{obj};
  1892. }
  1893. $self->fatal_error(
  1894. code => $_,
  1895. pos => pos($_),
  1896. error => q{attempt of using an implicit method call on an inexistent "_" variable},
  1897. );
  1898. }
  1899. # Quoted words, numbers, vectors and matrices
  1900. # %w(...), %i(...), %n(...), %v(...), %m(...), «...», <...>
  1901. if (/\G%([wWinvm])\b/gc || /\G(?=(«|<(?!<)))/) {
  1902. my ($type) = $1;
  1903. my $strings = $self->get_quoted_words(code => $opt{code});
  1904. if ($type eq 'w' or $type eq '<') {
  1905. my @list = map { Sidef::Types::String::String->new(s{\\(?=[\\#\s])}{}gr) } @{$strings};
  1906. return Sidef::Types::Array::Array->new(\@list);
  1907. }
  1908. if ($type eq 'i') {
  1909. my @list = map { Sidef::Types::Number::Number->new(s{\\(?=[\\#\s])}{}gr)->int }
  1910. split(/[\s,]+/, join(' ', @$strings));
  1911. return Sidef::Types::Array::Array->new(\@list);
  1912. }
  1913. if ($type eq 'n') {
  1914. my @list =
  1915. map { Sidef::Types::Number::Number->new(s{\\(?=[\\#\s])}{}gr) } split(/[\s,]+/, join(' ', @$strings));
  1916. return Sidef::Types::Array::Array->new(\@list);
  1917. }
  1918. if ($type eq 'v') {
  1919. my @list =
  1920. map { Sidef::Types::Number::Number->new(s{\\(?=[\\#\s])}{}gr) } split(/[\s,]+/, join(' ', @$strings));
  1921. return Sidef::Types::Array::Vector->new(@list); # this must be passed as a list
  1922. }
  1923. if ($type eq 'm') {
  1924. my @matrix;
  1925. my $data = join(' ', @$strings);
  1926. foreach my $line (split(/\s*;\s*/, $data)) {
  1927. my @row = map { Sidef::Types::Number::Number->new(s{\\(?=[\\#\s])}{}gr) } split(/[\s,]+/, $line);
  1928. push @matrix, Sidef::Types::Array::Array->new(\@row);
  1929. }
  1930. return Sidef::Types::Array::Matrix->new(@matrix);
  1931. }
  1932. my ($inline_expression, @objs);
  1933. foreach my $item (@{$strings}) {
  1934. my $str = Sidef::Types::String::String->new($item)->apply_escapes($self);
  1935. $inline_expression ||= ref($str) eq 'HASH';
  1936. push @objs, $str;
  1937. }
  1938. return (
  1939. $inline_expression
  1940. ? bless([map { {self => $_} } @objs], 'Sidef::Types::Array::HCArray')
  1941. : Sidef::Types::Array::Array->new(\@objs)
  1942. );
  1943. }
  1944. # Prefix method call (`::name(...)` or `::name ...`)
  1945. if (/\G::($self->{var_name_re})\h*/goc) {
  1946. my $name = $1;
  1947. my $pos = pos($_);
  1948. my $arg = (
  1949. /\G(?=\()/
  1950. ? $self->parse_arg(code => $opt{code})
  1951. : $self->parse_obj(code => $opt{code})
  1952. );
  1953. if (not exists($arg->{$self->{class}})) {
  1954. $self->fatal_error(
  1955. code => $_,
  1956. pos => ($pos - length($name)),
  1957. var => $name,
  1958. error => "attempt to call method <$name> on an undefined value",
  1959. );
  1960. }
  1961. return
  1962. bless {
  1963. name => $name,
  1964. expr => $arg,
  1965. },
  1966. 'Sidef::Meta::PrefixMethod';
  1967. }
  1968. if (/($self->{prefix_obj_re})\h*/goc) {
  1969. return ($^R, 1, $1);
  1970. }
  1971. # Assertions
  1972. if (/\G(assert(?:_(?:eq|ne))?+)\b\h*/gc) {
  1973. my $action = $1;
  1974. my $arg = (
  1975. /\G(?=\()/
  1976. ? $self->parse_arg(code => $opt{code})
  1977. : $self->parse_obj(code => $opt{code})
  1978. );
  1979. return
  1980. bless(
  1981. {
  1982. arg => $arg,
  1983. act => $action,
  1984. line => $self->{line},
  1985. file => $self->{file_name},
  1986. },
  1987. 'Sidef::Meta::Assert'
  1988. );
  1989. }
  1990. # die/warn
  1991. if (/\G(die|warn)\b\h*/gc) {
  1992. my $action = $1;
  1993. my $arg = (
  1994. /\G(?=\()/
  1995. ? $self->parse_arg(code => $opt{code})
  1996. : $self->parse_obj(code => $opt{code})
  1997. );
  1998. return
  1999. bless(
  2000. {
  2001. arg => $arg,
  2002. line => $self->{line},
  2003. file => $self->{file_name},
  2004. },
  2005. $action eq 'die'
  2006. ? "Sidef::Meta::Error"
  2007. : "Sidef::Meta::Warning"
  2008. );
  2009. }
  2010. # Eval keyword
  2011. if (/\Geval\b\h*/gc) {
  2012. my $obj = (
  2013. /\G(?=\()/
  2014. ? $self->parse_arg(code => $opt{code})
  2015. : $self->parse_obj(code => $opt{code})
  2016. );
  2017. #<<<
  2018. return bless(
  2019. {
  2020. expr => $obj,
  2021. parser => Sidef::Object::Object::dclone(scalar {%$self}),
  2022. #vars => {$self->{class} => [@{$self->{vars}{$self->{class}}}]},
  2023. #ref_vars_refs => {$self->{class} => [@{$self->{ref_vars_refs}{$self->{class}}}]},
  2024. }, 'Sidef::Eval::Eval');
  2025. #>>>
  2026. }
  2027. if (/\GParser\b/gc) {
  2028. return $self;
  2029. }
  2030. # Regular expression
  2031. if (m{\G(?=/)} || /\G%r\b/gc) {
  2032. my $string = $self->get_quoted_string(code => $opt{code});
  2033. return Sidef::Types::Regex::Regex->new($string, /\G($self->{match_flags_re})/goc ? $1 : undef);
  2034. }
  2035. # Class variable in form of `Class!var_name`
  2036. if (/\G($self->{var_name_re})!($self->{var_name_re})/goc) {
  2037. my ($class_name, $var_name) = ($1, $2);
  2038. my $class_obj = $self->parse_expr(code => \$class_name);
  2039. return (bless {class => $class_obj, name => $var_name}, 'Sidef::Variable::ClassVar');
  2040. }
  2041. # Static object (like String or nil)
  2042. if (/$self->{static_obj_re}/goc) {
  2043. return $^R;
  2044. }
  2045. if (/\G__MAIN__\b/gc) {
  2046. if (-e $self->{script_name}) {
  2047. state $x = require Cwd;
  2048. return Sidef::Types::String::String->new(Cwd::abs_path($self->{script_name}));
  2049. }
  2050. return Sidef::Types::String::String->new($self->{script_name});
  2051. }
  2052. if (/\G__FILE__\b/gc) {
  2053. if (-e $self->{file_name}) {
  2054. state $x = require Cwd;
  2055. return Sidef::Types::String::String->new(Cwd::abs_path($self->{file_name}));
  2056. }
  2057. return Sidef::Types::String::String->new($self->{file_name});
  2058. }
  2059. if (/\G__DATE__\b/gc) {
  2060. my (undef, undef, undef, $day, $mon, $year) = localtime;
  2061. return Sidef::Types::String::String->new(join('-', $year + 1900, map { sprintf "%02d", $_ } $mon + 1, $day));
  2062. }
  2063. if (/\G__TIME__\b/gc) {
  2064. my ($sec, $min, $hour) = localtime;
  2065. return Sidef::Types::String::String->new(join(':', map { sprintf "%02d", $_ } $hour, $min, $sec));
  2066. }
  2067. if (/\G__LINE__\b/gc) {
  2068. return Sidef::Types::Number::Number->new($self->{line});
  2069. }
  2070. if (/\G__COMPILED__\b/gc) {
  2071. return Sidef::Types::Bool::Bool->new($self->{opt}{R} eq 'Perl' or $self->{opt}{c});
  2072. }
  2073. if (/\G__OPTIMIZED__\b/gc) {
  2074. return Sidef::Types::Bool::Bool->new(($self->{opt}{O} || 0) > 0);
  2075. }
  2076. if (/\G__(?:END|DATA)__\b\h*+\R?/gc) {
  2077. if (exists $self->{'__DATA__'}) {
  2078. $self->{'__DATA__'} = substr($_, pos);
  2079. }
  2080. pos($_) = length($_);
  2081. return;
  2082. }
  2083. if (/\GDATA\b/gc) {
  2084. return (
  2085. $self->{static_objects}{'__DATA__'} //= do {
  2086. bless({data => \$self->{'__DATA__'}}, 'Sidef::Meta::Glob::DATA');
  2087. }
  2088. );
  2089. }
  2090. # Beginning of a here-document (<<"EOT", <<'EOT', <<EOT)
  2091. if (/\G<<(-)?+(?=\S)/gc) {
  2092. my $indent = $1 ? 1 : 0;
  2093. my ($name, $type) = (undef, 1);
  2094. my $pos = pos($_);
  2095. if (/\G(?=(['"„]))/) {
  2096. $type = 0 if $1 eq q{'};
  2097. my $str = $self->get_quoted_string(code => $opt{code});
  2098. $name = $str;
  2099. }
  2100. elsif (/\G(\w+)/gc) {
  2101. $name = $1;
  2102. }
  2103. else {
  2104. $self->fatal_error(
  2105. error => "invalid 'here-doc' declaration",
  2106. reason => "expected an alpha-numeric token after '<<'",
  2107. code => $_,
  2108. pos => pos($_)
  2109. );
  2110. }
  2111. my $obj = {$self->{class} => []};
  2112. push @{$self->{EOT}},
  2113. {
  2114. name => $name,
  2115. indent => $indent,
  2116. type => $type,
  2117. obj => $obj,
  2118. pos => $pos,
  2119. line => $self->{line},
  2120. };
  2121. return $obj;
  2122. }
  2123. if (exists($self->{current_block}) && /\G__BLOCK__\b/gc) {
  2124. return $self->{current_block};
  2125. }
  2126. if (/\G__NAMESPACE__\b/gc) {
  2127. return Sidef::Types::String::String->new($self->{class});
  2128. }
  2129. if (exists($self->{current_function})) {
  2130. /\G__FUNC__\b/gc && return $self->{current_function};
  2131. /\G__FUNC_NAME__\b/gc && return Sidef::Types::String::String->new($self->{current_function}{name});
  2132. }
  2133. if (exists($self->{current_class})) {
  2134. /\G__CLASS__\b/gc && return $self->{current_class};
  2135. /\G__CLASS_NAME__\b/gc && return Sidef::Types::String::String->new($self->{class_name});
  2136. }
  2137. if (exists($self->{current_method})) {
  2138. /\G__METHOD__\b/gc && return $self->{current_method};
  2139. /\G__METHOD_NAME__\b/gc && return Sidef::Types::String::String->new($self->{current_method}{name});
  2140. }
  2141. # Variable access
  2142. if (/\G($self->{var_name_re})/goc) {
  2143. my $len_var = length($1);
  2144. my ($name, $class) = $self->get_name_and_class($1);
  2145. if (defined(my $var = $self->find_var($name, $class))) {
  2146. if ($var->{type} eq 'del') {
  2147. $self->fatal_error(
  2148. code => $_,
  2149. pos => (pos($_) - length($name)),
  2150. var => ($class . '::' . $name),
  2151. error => "attempt to use the deleted variable <$name>",
  2152. );
  2153. }
  2154. $var->{count}++;
  2155. return $var->{obj};
  2156. }
  2157. if ($name eq 'ARGV' or $name eq 'ENV') {
  2158. my $type = 'var';
  2159. my $variable = bless({name => $name, type => $type, class => $class}, 'Sidef::Variable::Variable');
  2160. unshift @{$self->{vars}{$class}},
  2161. {
  2162. obj => $variable,
  2163. name => $name,
  2164. count => 1,
  2165. type => $type,
  2166. line => $self->{line},
  2167. };
  2168. return $variable;
  2169. }
  2170. # Class instance variables
  2171. if (
  2172. ref($self->{current_class}) eq 'Sidef::Variable::ClassInit'
  2173. and defined(
  2174. my $var = (first { $_->{name} eq $name } (@{$self->{current_class}{vars}}, map { @{$_->{vars}} } @{$self->{current_class}{attributes}}))
  2175. )
  2176. ) {
  2177. if (exists $self->{current_method}) {
  2178. if (defined(my $var = $self->find_var('self', $class))) {
  2179. if ($self->{opt}{k}) {
  2180. print STDERR "[INFO] `$name` is parsed as `self.$name` at $self->{file_name} line $self->{line}\n";
  2181. }
  2182. $var->{count}++;
  2183. return
  2184. scalar {
  2185. $self->{class} => [
  2186. {
  2187. self => $var->{obj},
  2188. ind => [{hash => [$name]}],
  2189. }
  2190. ]
  2191. };
  2192. }
  2193. }
  2194. elsif (exists $self->{allow_class_variable}) {
  2195. return $var;
  2196. }
  2197. elsif ($var->{type} eq 'has') {
  2198. $self->fatal_error(
  2199. error => "class variable <<$var->{name}>> can't be used outside a method",
  2200. pos => (pos($_) - length($name)),
  2201. var => $var,
  2202. code => $_,
  2203. );
  2204. }
  2205. else { # this should not happen
  2206. $self->fatal_error(
  2207. error => "can't use undeclared variable <<$var->{name}>> in this context",
  2208. pos => (pos($_) - length($name)),
  2209. var => $var,
  2210. code => $_,
  2211. );
  2212. }
  2213. }
  2214. if (/\G(?=\h*:?=(?![=~>]))/) {
  2215. if (not $self->{interactive}) {
  2216. warn "[WARNING] Implicit declaration of global variable `$name`" . " at $self->{file_name} line $self->{line}\n";
  2217. }
  2218. my $code = "global $name";
  2219. return $self->parse_expr(code => \$code);
  2220. }
  2221. # Method call in functional style (deprecated -- use `::name()` instead)
  2222. if ($len_var == length($name)) {
  2223. if ($self->{opt}{k}) {
  2224. print STDERR "[INFO] `$name` is parsed as a prefix method-call at $self->{file_name} line $self->{line}\n";
  2225. }
  2226. if ($self->{allow_class_variable}) {
  2227. return $name;
  2228. }
  2229. my $pos = pos($_);
  2230. my $arg = (
  2231. /\G\h*+(?=\()/gc
  2232. ? $self->parse_arg(code => $opt{code})
  2233. : $self->fatal_error(
  2234. code => $_,
  2235. pos => ($pos - length($name)),
  2236. var => ($class . '::' . $name),
  2237. error => "variable <$name> is not declared in the current scope",
  2238. )
  2239. );
  2240. if (not exists($arg->{$self->{class}})) {
  2241. $self->fatal_error(
  2242. code => $_,
  2243. pos => ($pos - length($name)),
  2244. var => $name,
  2245. error => "attempt to call method <$name> on an undefined value",
  2246. );
  2247. }
  2248. return
  2249. bless {
  2250. name => $name,
  2251. expr => $arg,
  2252. },
  2253. 'Sidef::Meta::PrefixMethod';
  2254. }
  2255. # Undeclared variable
  2256. $self->fatal_error(
  2257. code => $_,
  2258. pos => (pos($_) - length($name)),
  2259. var => ($class . '::' . $name),
  2260. error => "variable <$class\::$name> is not declared in the current scope",
  2261. );
  2262. }
  2263. # Regex variables ($1, $2, ...)
  2264. if (/\G\$([0-9]+)\b/gc) {
  2265. $self->fatal_error(
  2266. code => $_,
  2267. pos => (pos($_) - length($1)),
  2268. error => "regex capture-variables are not supported",
  2269. );
  2270. }
  2271. /\G\$/gc && redo;
  2272. #warn "$self->{script_name}:$self->{line}: unexpected char: " . substr($_, pos($_), 1) . "\n";
  2273. #return undef, pos($_) + 1;
  2274. return;
  2275. }
  2276. }
  2277. sub parse_arg {
  2278. my ($self, %opt) = @_;
  2279. local *_ = $opt{code};
  2280. if (/\G\(/gc) {
  2281. my $p = pos($_);
  2282. local $self->{parentheses} = 1;
  2283. my $obj = $self->parse_script(code => $opt{code});
  2284. $self->{parentheses}
  2285. && $self->fatal_error(
  2286. code => $_,
  2287. pos => $p - 1,
  2288. error => "unbalanced parenthesis",
  2289. );
  2290. return $obj;
  2291. }
  2292. return;
  2293. }
  2294. sub parse_array {
  2295. my ($self, %opt) = @_;
  2296. local *_ = $opt{code};
  2297. if (/\G\[/gc) {
  2298. my $p = pos($_);
  2299. local $self->{right_brackets} = 1;
  2300. my $obj = $self->parse_script(code => $opt{code});
  2301. $self->{right_brackets}
  2302. && $self->fatal_error(
  2303. code => $_,
  2304. pos => $p - 1,
  2305. error => "unbalanced right bracket",
  2306. );
  2307. return $obj;
  2308. }
  2309. return;
  2310. }
  2311. sub parse_lookup {
  2312. my ($self, %opt) = @_;
  2313. local *_ = $opt{code};
  2314. if (/\G\{/gc) {
  2315. my $p = pos($_);
  2316. local $self->{curly_brackets} = 1;
  2317. my $obj = $self->parse_script(code => $opt{code});
  2318. $self->{curly_brackets}
  2319. && $self->fatal_error(
  2320. code => $_,
  2321. pos => $p - 1,
  2322. error => "unbalanced curly bracket",
  2323. );
  2324. return $obj;
  2325. }
  2326. return;
  2327. }
  2328. sub parse_block {
  2329. my ($self, %opt) = @_;
  2330. local *_ = $opt{code};
  2331. if (/\G\{/gc) {
  2332. my $p = pos($_);
  2333. local $self->{curly_brackets} = 1;
  2334. my $class_name = $self->{class};
  2335. if ($opt{is_module}) {
  2336. $class_name = $opt{prev_class};
  2337. }
  2338. my $ref = $self->{vars}{$class_name} //= [];
  2339. my $count = scalar(@{$self->{vars}{$class_name}});
  2340. unshift @{$self->{ref_vars_refs}{$class_name}}, @{$ref};
  2341. unshift @{$self->{vars}{$class_name}}, [];
  2342. $self->{vars}{$class_name} = $self->{vars}{$class_name}[0];
  2343. my $block = bless({}, 'Sidef::Types::Block::BlockInit');
  2344. # Parse whitespace (if any)
  2345. $self->parse_whitespace(code => $opt{code});
  2346. my $has_vars;
  2347. my $var_objs = [];
  2348. if (($opt{topic_var} || $opt{with_vars}) && /\G(?=\|)/) {
  2349. $has_vars = 1;
  2350. $var_objs = $self->parse_init_vars(
  2351. params => 1,
  2352. code => $opt{code},
  2353. type => 'var',
  2354. );
  2355. }
  2356. # Special '_' variable
  2357. if ($opt{topic_var} and not $has_vars) {
  2358. my $code = '_';
  2359. $has_vars = 1;
  2360. $var_objs = $self->parse_init_vars(code => \$code, type => 'var');
  2361. }
  2362. local $self->{current_block} = $block if $has_vars;
  2363. my $obj = $self->parse_script(code => $opt{code});
  2364. $self->{curly_brackets}
  2365. && $self->fatal_error(
  2366. code => $_,
  2367. pos => $p - 1,
  2368. error => "unbalanced curly bracket",
  2369. );
  2370. #$block->{vars} = [
  2371. # map { $_->{obj} }
  2372. # grep { ref($_) eq 'HASH' and ref($_->{obj}) eq 'Sidef::Variable::Variable' } @{$self->{vars}{$class_name}}
  2373. #];
  2374. if ($has_vars) {
  2375. $block->{init_vars} = bless({vars => $var_objs}, 'Sidef::Variable::Init');
  2376. }
  2377. $block->{code} = $obj;
  2378. splice @{$self->{ref_vars_refs}{$class_name}}, 0, $count;
  2379. $self->{vars}{$class_name} = $ref;
  2380. return $block;
  2381. }
  2382. return;
  2383. }
  2384. sub append_method {
  2385. my ($self, %opt) = @_;
  2386. # Hyper-operator
  2387. if (exists $self->{hyper_ops}{$opt{op_type}}) {
  2388. push @{$opt{array}},
  2389. {
  2390. method => $self->{hyper_ops}{$opt{op_type}}[1],
  2391. arg => [$opt{method}],
  2392. };
  2393. }
  2394. # Basic operator/method
  2395. else {
  2396. push @{$opt{array}}, {method => $opt{method}};
  2397. }
  2398. # Append the argument (if any)
  2399. if (exists($opt{arg}) and (%{$opt{arg}} || ($opt{method} =~ /^$self->{operators_re}\z/))) {
  2400. push @{$opt{array}[-1]{arg}}, $opt{arg};
  2401. }
  2402. }
  2403. sub parse_methods {
  2404. my ($self, %opt) = @_;
  2405. my @methods;
  2406. local *_ = $opt{code};
  2407. my $orig_pos = pos($_);
  2408. {
  2409. if ((/\G(?![-=]>)/ && /\G(?=$self->{operators_re})/o) || /\G\./gc) {
  2410. my ($method, $req_arg, $op_type) = $self->get_method_name(code => $opt{code});
  2411. if (defined($method)) {
  2412. my $has_arg;
  2413. if (/\G\h*(?=[({])/gc || $req_arg) {
  2414. my $arg = (
  2415. $req_arg ? $self->parse_obj(code => $opt{code}, multiline => 1)
  2416. : /\G(?=\()/ ? $self->parse_arg(code => $opt{code})
  2417. : /\G(?=\{)/ ? $self->parse_block(code => $opt{code}, topic_var => 1)
  2418. : die "[PARSER ERROR] Something is wrong in the if condition"
  2419. );
  2420. if (defined $arg) {
  2421. $has_arg = 1;
  2422. $self->append_method(
  2423. array => \@methods,
  2424. method => $method,
  2425. arg => $arg,
  2426. op_type => $op_type,
  2427. );
  2428. }
  2429. else {
  2430. $self->fatal_error(
  2431. code => $_,
  2432. pos => $orig_pos,
  2433. error => "operator `$method` requires a right-side operand",
  2434. );
  2435. }
  2436. }
  2437. $has_arg || do {
  2438. $self->append_method(
  2439. array => \@methods,
  2440. method => $method,
  2441. op_type => $op_type,
  2442. );
  2443. };
  2444. redo;
  2445. }
  2446. }
  2447. }
  2448. return \@methods;
  2449. }
  2450. sub parse_suffixes {
  2451. my ($self, %opt) = @_;
  2452. my $struct = $opt{struct};
  2453. local *_ = $opt{code};
  2454. my $parsed = 0;
  2455. if (/\G(?=[\{\[])/) {
  2456. #<<<
  2457. $struct->{$self->{class}}[-1]{self} = {
  2458. $self->{class} => [
  2459. {
  2460. self => $struct->{$self->{class}}[-1]{self},
  2461. exists($struct->{$self->{class}}[-1]{call})
  2462. ? (call => delete $struct->{$self->{class}}[-1]{call})
  2463. : (),
  2464. exists($struct->{$self->{class}}[-1]{ind})
  2465. ? (ind => delete $struct->{$self->{class}}[-1]{ind})
  2466. : (),
  2467. }
  2468. ]
  2469. };
  2470. #>>>
  2471. }
  2472. {
  2473. if (/\G(?=\{)/) {
  2474. while (/\G(?=\{)/) {
  2475. my $lookup = $self->parse_lookup(code => $opt{code});
  2476. push @{$struct->{$self->{class}}[-1]{ind}}, {hash => $lookup->{$self->{class}}};
  2477. }
  2478. $parsed ||= 1;
  2479. redo;
  2480. }
  2481. if (/\G(?=\[)/) {
  2482. while (/\G(?=\[)/) {
  2483. my ($ind) = $self->parse_expr(code => $opt{code});
  2484. push @{$struct->{$self->{class}}[-1]{ind}}, {array => $ind};
  2485. }
  2486. $parsed ||= 1;
  2487. redo;
  2488. }
  2489. if (/\G\h*(?=\()/gc) {
  2490. #<<<
  2491. $struct->{$self->{class}}[-1]{self} = {
  2492. $self->{class} => [
  2493. {
  2494. self => $struct->{$self->{class}}[-1]{self},
  2495. exists($struct->{$self->{class}}[-1]{call})
  2496. ? (call => delete $struct->{$self->{class}}[-1]{call})
  2497. : (),
  2498. exists($struct->{$self->{class}}[-1]{ind})
  2499. ? (ind => delete $struct->{$self->{class}}[-1]{ind})
  2500. : (),
  2501. }
  2502. ]
  2503. };
  2504. #>>>
  2505. my $arg = $self->parse_arg(code => $opt{code});
  2506. push @{$struct->{$self->{class}}[-1]{call}},
  2507. {
  2508. method => 'call',
  2509. (%{$arg} ? (arg => [$arg]) : ())
  2510. };
  2511. redo;
  2512. }
  2513. }
  2514. $parsed;
  2515. }
  2516. sub backtrack_whitespace {
  2517. my ($self, %opt) = @_;
  2518. local *_ = $opt{code};
  2519. # Backtrack the removal of whitespace
  2520. while (1) {
  2521. my $s = substr($_, pos($_) - 1, 1);
  2522. if ($s =~ /\R/) {
  2523. $self->{line} -= 1;
  2524. pos($_) -= 1;
  2525. last;
  2526. }
  2527. elsif ($s =~ /\h/) {
  2528. pos($_) -= 1;
  2529. }
  2530. else {
  2531. last;
  2532. }
  2533. }
  2534. }
  2535. sub parse_obj {
  2536. my ($self, %opt) = @_;
  2537. my %struct;
  2538. local *_ = $opt{code};
  2539. if (not($opt{multiline}) and /\G\h*(?=\R)/gc) {
  2540. $self->fatal_error(
  2541. code => $_,
  2542. pos => pos($_) - 1,
  2543. error => "unexpected end-of-statement",
  2544. );
  2545. }
  2546. my ($obj, $obj_key, $method) = $self->parse_expr(code => $opt{code});
  2547. if (defined $obj) {
  2548. push @{$struct{$self->{class}}}, {self => $obj};
  2549. # for var in array { ... }
  2550. if (ref($obj) eq 'Sidef::Types::Block::For' and /\G\h*(?=[*:]?$self->{var_name_re})/goc) {
  2551. my $class_name = $self->{class};
  2552. my @loops;
  2553. {
  2554. my @vars;
  2555. while (/\G([*:])?($self->{var_name_re})/gc) {
  2556. my $type = $1;
  2557. my $name = $2;
  2558. push @vars,
  2559. bless(
  2560. {
  2561. name => $name,
  2562. type => 'var',
  2563. class => $class_name,
  2564. (
  2565. $type
  2566. ? (
  2567. slurpy => 1,
  2568. ($type eq '*' ? (array => 1) : (hash => 1)),
  2569. )
  2570. : ()
  2571. ),
  2572. },
  2573. 'Sidef::Variable::Variable'
  2574. );
  2575. unshift @{$self->{vars}{$class_name}},
  2576. {
  2577. obj => $vars[-1],
  2578. name => $name,
  2579. count => 1,
  2580. type => 'var',
  2581. line => $self->{line},
  2582. };
  2583. $type && last;
  2584. /\G\h*,\h*/gc || last;
  2585. }
  2586. /\G\h*(?:in|∈|=|)\h*/gc
  2587. || $self->fatal_error(
  2588. error => "expected the token <<in>> after variable declaration in for-loop",
  2589. code => $_,
  2590. pos => pos($_),
  2591. );
  2592. my $expr = (
  2593. /\G(?=\()/
  2594. ? $self->parse_arg(code => $opt{code})
  2595. : $self->parse_obj(code => $opt{code})
  2596. );
  2597. push @loops,
  2598. {
  2599. vars => \@vars,
  2600. expr => $expr,
  2601. };
  2602. /\G\h*,\h*/gc && redo;
  2603. }
  2604. my $block = (
  2605. /\G\h*(?=\{)/gc
  2606. ? $self->parse_block(code => $opt{code})
  2607. : $self->fatal_error(
  2608. error => "expected a block",
  2609. code => $_,
  2610. pos => pos($_),
  2611. )
  2612. );
  2613. # Remove the for-loop variables from the outer scope
  2614. #<<<
  2615. my %loop_vars = map {
  2616. map { refaddr($_) => 1 } @{$_->{vars}}
  2617. } @loops;
  2618. @{$self->{vars}{$class_name}} = grep {
  2619. ref($_) ne 'HASH'
  2620. or not exists $loop_vars{refaddr($_->{obj})}
  2621. } @{$self->{vars}{$class_name}};
  2622. #>>>
  2623. # Store the info
  2624. $obj->{block} = $block;
  2625. $obj->{loops} = \@loops;
  2626. # Re-bless the $obj into a different class
  2627. bless $obj, 'Sidef::Types::Block::ForIn';
  2628. }
  2629. elsif ($obj_key) {
  2630. my $arg = (
  2631. /\G(?=\()/
  2632. ? $self->parse_arg(code => $opt{code})
  2633. : $self->parse_obj(code => $opt{code})
  2634. );
  2635. if (defined $arg) {
  2636. my @arg = ($arg);
  2637. if (ref($obj) eq 'Sidef::Types::Block::For') {
  2638. if ($#{$arg->{$self->{class}}} == 2) {
  2639. @arg = (
  2640. map {
  2641. { $self->{class} => [$_] }
  2642. } @{$arg->{$self->{class}}}
  2643. );
  2644. if (/\G\h*(?=\{)/gc) {
  2645. my $block = $self->parse_block(code => $opt{code});
  2646. $obj->{expr} = \@arg;
  2647. $obj->{block} = $block;
  2648. bless $obj, 'Sidef::Types::Block::CFor';
  2649. }
  2650. else {
  2651. $self->fatal_error(
  2652. code => $_,
  2653. pos => pos($_) - 1,
  2654. error => "invalid declaration of the `for` loop",
  2655. reason => "expected a block after `for(;;)`",
  2656. );
  2657. }
  2658. }
  2659. elsif ($#{$arg->{$self->{class}}} == 0) {
  2660. if (/\G\h*(?=\{)/gc) {
  2661. my $block = $self->parse_block(code => $opt{code}, topic_var => 1);
  2662. $obj->{expr} = $arg;
  2663. $obj->{block} = $block;
  2664. bless $obj, 'Sidef::Types::Block::ForEach';
  2665. }
  2666. else {
  2667. $self->fatal_error(
  2668. code => $_,
  2669. pos => pos($_) - 1,
  2670. error => "invalid declaration of the `for` loop",
  2671. reason => "expected a block after `for(...)`",
  2672. );
  2673. }
  2674. }
  2675. else {
  2676. $self->fatal_error(
  2677. code => $_,
  2678. pos => pos($_) - 1,
  2679. error => "invalid declaration of the `for` loop: incorrect number of arguments",
  2680. );
  2681. }
  2682. }
  2683. elsif (ref($obj) eq 'Sidef::Types::Block::ForEach') {
  2684. if (/\G\h*(?=\{)/gc) {
  2685. my $block = $self->parse_block(code => $opt{code}, topic_var => 1);
  2686. $obj->{expr} = $arg;
  2687. $obj->{block} = $block;
  2688. }
  2689. else {
  2690. $self->fatal_error(
  2691. code => $_,
  2692. pos => pos($_) - 1,
  2693. error => "invalid declaration of the `foreach` loop",
  2694. reason => "expected a block after `foreach(...)`",
  2695. );
  2696. }
  2697. }
  2698. elsif (ref($obj) eq 'Sidef::Types::Block::If') {
  2699. if (/\G\h*(?=\{)/gc) {
  2700. my $block = $self->parse_block(code => $opt{code}, with_vars => 1);
  2701. push @{$obj->{if}}, {expr => $arg, block => $block};
  2702. ELSIF: {
  2703. $self->parse_whitespace(code => $opt{code});
  2704. if (/\Gelsif\h*(?=\()/gc) {
  2705. my $arg = $self->parse_arg(code => $opt{code});
  2706. $self->parse_whitespace(code => $opt{code});
  2707. my $block = $self->parse_block(code => $opt{code}, with_vars => 1) // $self->fatal_error(
  2708. code => $_,
  2709. pos => pos($_) - 1,
  2710. error => "invalid declaration of the `if` statement",
  2711. reason => "expected a block after `elsif(...)`",
  2712. );
  2713. push @{$obj->{if}}, {expr => $arg, block => $block};
  2714. redo ELSIF;
  2715. }
  2716. }
  2717. if (/\Gelse\h*(?=\{)/gc) {
  2718. my $block = $self->parse_block(code => $opt{code});
  2719. $obj->{else}{block} = $block;
  2720. }
  2721. $self->backtrack_whitespace(code => $opt{code});
  2722. }
  2723. else {
  2724. $self->fatal_error(
  2725. code => $_,
  2726. pos => pos($_) - 1,
  2727. error => "invalid declaration of the `if` statement",
  2728. reason => "expected a block after `if(...)`",
  2729. );
  2730. }
  2731. }
  2732. elsif (ref($obj) eq 'Sidef::Types::Block::With') {
  2733. if (/\G\h*(?=\{)/gc) {
  2734. my $block = $self->parse_block(code => $opt{code}, topic_var => 1);
  2735. push @{$obj->{with}}, {expr => $arg, block => $block};
  2736. ORWITH: {
  2737. $self->parse_whitespace(code => $opt{code});
  2738. if (/\Gorwith\h*(?=\()/gc) {
  2739. my $arg = $self->parse_arg(code => $opt{code});
  2740. $self->parse_whitespace(code => $opt{code});
  2741. my $block = $self->parse_block(code => $opt{code}, topic_var => 1) // $self->fatal_error(
  2742. code => $_,
  2743. pos => pos($_) - 1,
  2744. error => "invalid declaration of the `with` statement",
  2745. reason => "expected a block after `orwith(...)`",
  2746. );
  2747. push @{$obj->{with}}, {expr => $arg, block => $block};
  2748. redo ORWITH;
  2749. }
  2750. }
  2751. if (/\Gelse\h*(?=\{)/gc) {
  2752. my $block = $self->parse_block(code => $opt{code});
  2753. $obj->{else}{block} = $block;
  2754. }
  2755. $self->backtrack_whitespace(code => $opt{code});
  2756. }
  2757. else {
  2758. $self->fatal_error(
  2759. code => $_,
  2760. pos => pos($_) - 1,
  2761. error => "invalid declaration of the `with` statement",
  2762. reason => "expected a block after `with(...)`",
  2763. );
  2764. }
  2765. }
  2766. elsif (ref($obj) eq 'Sidef::Types::Block::While') {
  2767. if (/\G\h*(?=\{)/gc) {
  2768. my $block = $self->parse_block(code => $opt{code}, with_vars => 1);
  2769. $obj->{expr} = $arg;
  2770. $obj->{block} = $block;
  2771. }
  2772. else {
  2773. $self->fatal_error(
  2774. code => $_,
  2775. pos => pos($_) - 1,
  2776. error => "invalid declaration of the `while` statement",
  2777. reason => "expected a block after `while(...)`",
  2778. );
  2779. }
  2780. }
  2781. else {
  2782. push @{$struct{$self->{class}}[-1]{call}}, {method => $method, arg => \@arg};
  2783. }
  2784. }
  2785. else {
  2786. $self->fatal_error(
  2787. code => $_,
  2788. error => "expected an argument. Did you mean '$method()' instead?",
  2789. pos => pos($_) - 1,
  2790. );
  2791. }
  2792. }
  2793. {
  2794. # Method call
  2795. if (/\G\h*(?=\.\h*(?:$self->{method_name_re}|[(\$]))/ogc) {
  2796. my $methods = $self->parse_methods(code => $opt{code});
  2797. push @{$struct{$self->{class}}[-1]{call}}, @{$methods};
  2798. }
  2799. # Code extended on a newline
  2800. if (/\G\h*\\(?!\\)/gc) {
  2801. $self->parse_whitespace(code => $opt{code});
  2802. redo;
  2803. }
  2804. # Object call
  2805. if (/\G\h*(?=\()/gc) {
  2806. my $arg = $self->parse_arg(code => $opt{code});
  2807. push @{$struct{$self->{class}}[-1]{call}},
  2808. {
  2809. method => 'call',
  2810. (%{$arg} ? (arg => [$arg]) : ())
  2811. };
  2812. redo;
  2813. }
  2814. # Do-while construct
  2815. if (ref($obj) eq 'Sidef::Types::Block::Do' and /\G\h*while\b/gc) {
  2816. my $arg = $self->parse_obj(code => $opt{code});
  2817. push @{$struct{$self->{class}}[-1]{call}}, {keyword => 'while', arg => [$arg]};
  2818. }
  2819. # Parse array and hash fetchers ([...] and {...})
  2820. if (/\G\.\h*(?=[\[\{])/gc or 1) {
  2821. $self->parse_suffixes(code => $opt{code}, struct => \%struct) && redo;
  2822. }
  2823. # Tightly-binded operator
  2824. if (
  2825. /\G(?![=-]>)/ # not '=>' or '->'
  2826. && (
  2827. /\G(?=$self->{operators_re})/o # operator
  2828. || /\G\h*\.\h*(?!\.\.)(?=$self->{operators_re})/gco # dot followed by operator
  2829. || /\G(?=[⁰¹²³⁴⁵⁶⁷⁸⁹])/ # unicode superscript
  2830. )
  2831. ) {
  2832. my $orig_pos = pos($_);
  2833. my ($method, $req_arg, $op_type) = $self->get_method_name(code => $opt{code});
  2834. if (defined($method)) {
  2835. my $has_arg;
  2836. if ($req_arg) {
  2837. my $arg = $self->parse_obj(code => $opt{code}, multiline => 1);
  2838. if (defined $arg) {
  2839. if (ref $arg ne 'HASH') {
  2840. $arg = {$self->{class} => [{self => $arg}]};
  2841. }
  2842. my $methods = $self->parse_methods(code => $opt{code});
  2843. if (@{$methods}) {
  2844. push @{$arg->{$self->{class}}[-1]{call}}, @{$methods};
  2845. }
  2846. $has_arg = 1;
  2847. $self->append_method(
  2848. array => \@{$struct{$self->{class}}[-1]{call}},
  2849. method => $method,
  2850. arg => $arg,
  2851. op_type => $op_type,
  2852. );
  2853. }
  2854. else {
  2855. $self->fatal_error(
  2856. code => $_,
  2857. pos => $orig_pos,
  2858. error => "operator `$method` requires a right-side operand",
  2859. );
  2860. }
  2861. }
  2862. $has_arg || do {
  2863. $self->append_method(
  2864. array => \@{$struct{$self->{class}}[-1]{call}},
  2865. method => $method,
  2866. op_type => $op_type,
  2867. );
  2868. };
  2869. redo;
  2870. }
  2871. }
  2872. }
  2873. }
  2874. else {
  2875. return;
  2876. }
  2877. return \%struct;
  2878. }
  2879. sub parse_script {
  2880. my ($self, %opt) = @_;
  2881. my %struct;
  2882. local *_ = $opt{code};
  2883. MAIN: {
  2884. $self->parse_whitespace(code => $opt{code});
  2885. if (/\G\@:([^\W\d]\w*+)/gc) {
  2886. push @{$struct{$self->{class}}}, {self => bless({name => $1}, 'Sidef::Variable::Label')};
  2887. redo;
  2888. }
  2889. if (/\G(?:[;,]+|=>)/gc) {
  2890. redo;
  2891. }
  2892. my $obj;
  2893. # Ternary operator
  2894. if (%struct && /\G\?/gc) {
  2895. $self->parse_whitespace(code => $opt{code});
  2896. my $true = (
  2897. /\G(?=\()/
  2898. ? $self->parse_arg(code => $opt{code})
  2899. : $self->parse_obj(code => $opt{code})
  2900. );
  2901. $self->parse_whitespace(code => $opt{code});
  2902. /\G:/gc
  2903. || $self->fatal_error(
  2904. code => $_,
  2905. pos => pos($_),
  2906. error => "invalid usage of the ternary operator",
  2907. reason => "expected ':'",
  2908. );
  2909. $self->parse_whitespace(code => $opt{code});
  2910. my $false = (
  2911. /\G(?=\()/
  2912. ? $self->parse_arg(code => $opt{code})
  2913. : $self->parse_obj(code => $opt{code})
  2914. );
  2915. $obj = bless(
  2916. {
  2917. cond => scalar {$self->{class} => [pop @{$struct{$self->{class}}}]},
  2918. true => $true,
  2919. false => $false
  2920. },
  2921. 'Sidef::Types::Bool::Ternary'
  2922. );
  2923. }
  2924. else {
  2925. $obj = $self->parse_obj(code => $opt{code});
  2926. }
  2927. if (defined $obj) {
  2928. push @{$struct{$self->{class}}}, {self => $obj};
  2929. {
  2930. my $pos_before = pos($_);
  2931. $self->parse_whitespace(code => $opt{code});
  2932. # End of expression
  2933. if (/\G(?:[;,]+|=>)/gc or substr($_, $pos_before, pos($_) - $pos_before) =~ /\R/) {
  2934. redo MAIN;
  2935. }
  2936. # Code extended on a newline
  2937. if (/\G\\(?!\\)/gc) {
  2938. $self->parse_whitespace(code => $opt{code});
  2939. }
  2940. my $is_operator = /\G(?!->)/ && /\G(?=($self->{operators_re}))/o;
  2941. if ($is_operator or /\G(?:->|\.)\h*/gc) {
  2942. # Implicit end of statement -- redo
  2943. $self->parse_whitespace(code => $opt{code});
  2944. my $methods;
  2945. if ($is_operator) {
  2946. $methods = $self->parse_methods(code => $opt{code});
  2947. }
  2948. else {
  2949. my $code = substr($_, pos);
  2950. my $dot_op = $code =~ /^\./;
  2951. if ($dot_op) { $code = ". $code" }
  2952. else { $code = ".$code" }
  2953. $methods = $self->parse_methods(code => \$code);
  2954. pos($_) += pos($code) - ($dot_op ? 2 : 1);
  2955. }
  2956. if (@{$methods}) {
  2957. push @{$struct{$self->{class}}[-1]{call}}, @{$methods};
  2958. }
  2959. else {
  2960. $self->fatal_error(
  2961. error => 'incomplete method name',
  2962. code => $_,
  2963. pos => pos($_) - 1,
  2964. );
  2965. }
  2966. $self->parse_suffixes(code => $opt{code}, struct => \%struct);
  2967. redo;
  2968. }
  2969. elsif (/\G(if|while|and|or)\b\h*/gc) {
  2970. my $keyword = $1;
  2971. my $obj = $self->parse_obj(code => $opt{code});
  2972. push @{$struct{$self->{class}}[-1]{call}}, {keyword => $keyword, arg => [$obj]};
  2973. redo;
  2974. }
  2975. else {
  2976. redo MAIN;
  2977. }
  2978. }
  2979. }
  2980. if (/\G(?:[;,]+|=>)/gc) {
  2981. redo;
  2982. }
  2983. # We are at the end of the script.
  2984. # We make some checks, and return the \%struct hash ref.
  2985. if (/\G\z/) {
  2986. $self->check_declarations($self->{ref_vars});
  2987. return \%struct;
  2988. }
  2989. if (/\G\]/gc) {
  2990. if (--$self->{right_brackets} < 0) {
  2991. $self->fatal_error(
  2992. error => 'unbalanced right bracket',
  2993. code => $_,
  2994. pos => pos($_) - 1,
  2995. );
  2996. }
  2997. return \%struct;
  2998. }
  2999. if (/\G\}/gc) {
  3000. if (--$self->{curly_brackets} < 0) {
  3001. $self->fatal_error(
  3002. error => 'unbalanced curly bracket',
  3003. code => $_,
  3004. pos => pos($_) - 1,
  3005. );
  3006. }
  3007. return \%struct;
  3008. }
  3009. # The end of an argument expression
  3010. if (/\G\)/gc) {
  3011. if (--$self->{parentheses} < 0) {
  3012. $self->fatal_error(
  3013. error => 'unbalanced parenthesis',
  3014. code => $_,
  3015. pos => pos($_) - 1,
  3016. );
  3017. }
  3018. return \%struct;
  3019. }
  3020. $self->fatal_error(
  3021. code => $_,
  3022. pos => (pos($_)),
  3023. error => "expected a method",
  3024. );
  3025. pos($_) += 1;
  3026. redo;
  3027. }
  3028. }
  3029. };
  3030. 1