stmt.bmx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. ' Copyright (c) 2013-2016 Bruce A Henderson
  2. '
  3. ' Based on the public domain Monkey "trans" by Mark Sibly
  4. '
  5. ' This software is provided 'as-is', without any express or implied
  6. ' warranty. In no event will the authors be held liable for any damages
  7. ' arising from the use of this software.
  8. '
  9. ' Permission is granted to anyone to use this software for any purpose,
  10. ' including commercial applications, and to alter it and redistribute it
  11. ' freely, subject to the following restrictions:
  12. '
  13. ' 1. The origin of this software must not be misrepresented; you must not
  14. ' claim that you wrote the original software. If you use this software
  15. ' in a product, an acknowledgment in the product documentation would be
  16. ' appreciated but is not required.
  17. '
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. '
  21. ' 3. This notice may not be removed or altered from any source
  22. ' distribution.
  23. '
  24. Type TStmt
  25. Field errInfo$
  26. ' whether this statement was generated by the compiler or not
  27. Field generated:Int
  28. Method New()
  29. errInfo=_errInfo
  30. End Method
  31. Method OnCopy:TStmt( scope:TScopeDecl ) Abstract
  32. Method Semant()
  33. PushErr errInfo
  34. OnSemant
  35. PopErr
  36. End Method
  37. Method Copy:TStmt( scope:TScopeDecl )
  38. Local t:TStmt=OnCopy( scope )
  39. t.errInfo=errInfo
  40. Return t
  41. End Method
  42. Method OnSemant() Abstract
  43. Method Trans$() Abstract
  44. End Type
  45. Type TDeclStmt Extends TStmt
  46. Field decl:TDecl
  47. Method Create:TDeclStmt( decl:TDecl, generated:Int = False )
  48. Self.decl=decl
  49. Self.generated = generated
  50. Return Self
  51. End Method
  52. Method CreateWithId:TDeclStmt( id$,ty:TType,init:TExpr )
  53. Self.decl=New TLocalDecl.Create( id,ty,init,0 )
  54. Return Self
  55. End Method
  56. Method OnCopy:TStmt( scope:TScopeDecl )
  57. Return New TDeclStmt.Create( decl.Copy(), generated )
  58. End Method
  59. Method OnSemant()
  60. decl.Semant
  61. ' if scope is already set, don't try to add it to the current scope.
  62. If Not decl.scope Then
  63. _env.InsertDecl decl
  64. End If
  65. End Method
  66. Method Trans$()
  67. Return _trans.TransDeclStmt( Self )
  68. End Method
  69. End Type
  70. Type TAssignStmt Extends TStmt
  71. Field op$
  72. Field lhs:TExpr
  73. Field rhs:TExpr
  74. Method Create:TAssignStmt( op$,lhs:TExpr,rhs:TExpr, generated:Int = False )
  75. Self.op=op
  76. Self.lhs=lhs
  77. Self.rhs=rhs
  78. Self.generated = generated
  79. Return Self
  80. End Method
  81. Method OnCopy:TStmt( scope:TScopeDecl )
  82. Return New TAssignStmt.Create( op,lhs.Copy(),rhs.Copy(), generated )
  83. End Method
  84. Method OnSemant()
  85. If TIdentExpr(rhs) Then
  86. TIdentExpr(rhs).isRhs = True
  87. End If
  88. rhs=rhs.Semant()
  89. lhs=lhs.SemantSet( op,rhs )
  90. If TInvokeExpr( lhs ) Or TInvokeMemberExpr( lhs )
  91. rhs=Null
  92. Else
  93. If IsPointerType(lhs.exprType, 0, TType.T_POINTER | TType.T_VARPTR) And TNumericType(rhs.exprType) Then
  94. ' with pointer assignment we don't cast the numeric to a pointer
  95. Else If IsPointerType(lhs.exprType, 0, TType.T_VAR) And TNumericType(rhs.exprType) Then
  96. ' for var, we cast to the non-var type
  97. Local ty:TType = lhs.exprType.Copy()
  98. ty._flags :~ TType.T_VAR
  99. rhs=rhs.Cast( ty )
  100. Else
  101. Local splitOp:Int = True
  102. Select op
  103. Case "="
  104. rhs=rhs.Cast( lhs.exprType )
  105. splitOp = False
  106. Case ":*",":/",":+",":-"
  107. If TNumericType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType ) Then
  108. splitOp = False
  109. End If
  110. If TObjectType(lhs.exprType) Then
  111. Local args:TExpr[] = [rhs]
  112. Try
  113. Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,True,SCOPE_CLASS_HEIRARCHY))
  114. If decl Then
  115. lhs = New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
  116. rhs = Null
  117. Return
  118. End If
  119. Catch error:String
  120. Err "Operator " + op + " cannot be used with Objects."
  121. End Try
  122. End If
  123. Case ":&",":|",":^",":shl",":shr",":mod"
  124. If (TIntType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType )) Or TObjectType(lhs.exprType) Then
  125. splitOp = False
  126. End If
  127. If TObjectType(lhs.exprType) Then
  128. Local args:TExpr[] = [rhs]
  129. Try
  130. Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,,SCOPE_CLASS_HEIRARCHY))
  131. If decl Then
  132. lhs = New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
  133. rhs = Null
  134. Return
  135. End If
  136. Catch error:String
  137. Err "Operator " + op + " cannot be used with Objects."
  138. End Try
  139. End If
  140. End Select
  141. If splitOp Then
  142. rhs = New TBinaryMathExpr.Create(op[1..], lhs, rhs).Semant().Cast(lhs.exprType)
  143. op = "="
  144. End If
  145. End If
  146. EndIf
  147. End Method
  148. Method Trans$()
  149. _errInfo=errInfo
  150. Return _trans.TransAssignStmt( Self )
  151. End Method
  152. End Type
  153. Type TExprStmt Extends TStmt
  154. Field expr:TExpr
  155. Method Create:TExprStmt( expr:TExpr )
  156. Self.expr=expr
  157. Return Self
  158. End Method
  159. Method OnCopy:TStmt( scope:TScopeDecl )
  160. Return New TExprStmt.Create( expr.Copy() )
  161. End Method
  162. Method OnSemant()
  163. expr=expr.Semant()
  164. If Not expr InternalErr
  165. End Method
  166. Method Trans$()
  167. Return _trans.TransExprStmt( Self )
  168. End Method
  169. End Type
  170. Type TReturnStmt Extends TStmt
  171. Field expr:TExpr
  172. Field fRetType:TType
  173. Method Create:TReturnStmt( expr:TExpr )
  174. Self.expr=expr
  175. Return Self
  176. End Method
  177. Method OnCopy:TStmt( scope:TScopeDecl )
  178. If expr Return New TReturnStmt.Create( expr.Copy() )
  179. Return New TReturnStmt.Create( Null )
  180. End Method
  181. Method OnSemant()
  182. Local fdecl:TFuncDecl=_env.FuncScope()
  183. If expr
  184. If TIdentExpr(expr) Then
  185. TIdentExpr(expr).isRhs = True
  186. End If
  187. If fdecl.IsCtor() Err "Constructors may not return a value."
  188. If TVoidType( fdecl.retType ) Then
  189. Local errorText:String = "Function can not return a value."
  190. If Not _env.ModuleScope().IsSuperStrict() Then
  191. errorText :+ " You may have Strict type overriding SuperStrict type."
  192. End If
  193. Err errorText
  194. End If
  195. fRetType = fdecl.retType
  196. expr=expr.SemantAndCast( fdecl.retType )
  197. Else If fdecl.IsCtor()
  198. expr=New TSelfExpr.Semant()
  199. Else If Not TVoidType( fdecl.retType )
  200. If _env.ModuleScope().IsSuperStrict() Err "Function must return a value"
  201. expr=New TConstExpr.Create( fdecl.retType,"" ).Semant()
  202. EndIf
  203. End Method
  204. Method Trans$()
  205. Return _trans.TransReturnStmt( Self )
  206. End Method
  207. End Type
  208. Type TTryStmt Extends TStmt
  209. Field block:TBlockDecl
  210. Field catches:TCatchStmt[]
  211. Method Create:TTryStmt( block:TBlockDecl,catches:TCatchStmt[] )
  212. Self.block=block
  213. Self.catches=catches
  214. Return Self
  215. End Method
  216. Method OnCopy:TStmt( scope:TScopeDecl )
  217. Local tcatches:TCatchStmt[] = Self.catches[..]
  218. For Local i:Int=0 Until tcatches.Length
  219. tcatches[i]=TCatchStmt( tcatches[i].Copy( scope ) )
  220. Next
  221. Return New TTryStmt.Create( block.CopyBlock( scope ),tcatches )
  222. End Method
  223. Method OnSemant()
  224. block.Semant
  225. Local hasObject:Int = False
  226. For Local i:Int = 0 Until catches.Length
  227. catches[i].Semant
  228. If hasObject Then
  229. PushErr catches[i].errInfo
  230. Err "Catch variable class extends earlier catch variable class"
  231. End If
  232. If TObjectType(catches[i].init.ty) And TObjectType(catches[i].init.ty).classdecl.ident = "Object" Then
  233. hasObject = True
  234. Continue
  235. End If
  236. For Local j:Int = 0 Until i
  237. If catches[i].init.ty.ExtendsType( catches[j].init.ty )
  238. PushErr catches[i].errInfo
  239. Err "Catch variable class extends earlier catch variable class"
  240. EndIf
  241. Next
  242. Next
  243. End Method
  244. Method Trans$()
  245. Return _trans.TransTryStmt( Self )
  246. End Method
  247. End Type
  248. Type TCatchStmt Extends TStmt
  249. Field init:TLocalDecl
  250. Field block:TBlockDecl
  251. Method Create:TCatchStmt( init:TLocalDecl,block:TBlockDecl )
  252. Self.init=init
  253. Self.block=block
  254. Return Self
  255. End Method
  256. Method OnCopy:TStmt( scope:TScopeDecl )
  257. Return New TCatchStmt.Create( TLocalDecl( init.Copy() ),block.CopyBlock( scope ) )
  258. End Method
  259. Method OnSemant()
  260. init.Semant
  261. If Not TObjectType( init.ty ) And Not TStringType(init.ty) Err "Variable type must extend Throwable"
  262. 'If Not init.Type.GetClass().IsThrowable() Err "Variable type must extend Throwable"
  263. block.InsertDecl init
  264. block.Semant
  265. End Method
  266. Method Trans$()
  267. End Method
  268. End Type
  269. Type TThrowStmt Extends TStmt
  270. Field expr:TExpr
  271. Method Create:TThrowStmt( expr:TExpr )
  272. Self.expr=expr
  273. Return Self
  274. End Method
  275. Method OnCopy:TStmt( scope:TScopeDecl )
  276. Return New TThrowStmt.Create( expr.Copy() )
  277. End Method
  278. Method OnSemant()
  279. expr=expr.Semant()
  280. If Not TObjectType( expr.exprType ) And Not TStringType(expr.exprType) Err "Expression Type must extend Throwable"
  281. 'If Not expr.exprType.GetClass().IsThrowable() Err "Expression type must extend Throwable"
  282. End Method
  283. Method Trans$()
  284. ' TODO
  285. Return _trans.TransThrowStmt( Self )
  286. End Method
  287. End Type
  288. Type TBreakStmt Extends TStmt
  289. Field loop:TLoopStmt
  290. Field label:TExpr
  291. Method Create:TBreakStmt( label:TExpr )
  292. Self.label=label
  293. Return Self
  294. End Method
  295. Method OnSemant()
  296. If Not _loopnest Err "Exit statement must appear inside a loop."
  297. If label Then
  298. label = label.Semant()
  299. End If
  300. If opt_debug And Not loop Then
  301. loop = TLoopStmt(_env.FindLoop())
  302. If Not loop Err "Cannot find loop for Exit."
  303. End If
  304. End Method
  305. Method OnCopy:TStmt( scope:TScopeDecl )
  306. Return New TBreakStmt.Create(label.Copy())
  307. End Method
  308. Method Trans$()
  309. Return _trans.TransBreakStmt( Self )
  310. End Method
  311. End Type
  312. Type TContinueStmt Extends TStmt
  313. Field loop:TLoopStmt
  314. Field label:TExpr
  315. Method Create:TContinueStmt( label:TExpr, generated:Int = False )
  316. Self.label=label
  317. Self.generated = generated
  318. Return Self
  319. End Method
  320. Method OnSemant()
  321. If Not _loopnest Err "Continue statement must appear inside a loop."
  322. If label Then
  323. label = label.Semant()
  324. End If
  325. If opt_debug And Not loop Then
  326. loop = TLoopStmt(_env.FindLoop())
  327. If Not loop Err "Cannot find loop for Continue."
  328. End If
  329. End Method
  330. Method OnCopy:TStmt( scope:TScopeDecl )
  331. If label Then
  332. Return New TContinueStmt.Create(label.Copy(), generated)
  333. Else
  334. Return New TContinueStmt.Create(Null, generated)
  335. End If
  336. End Method
  337. Method Trans$()
  338. Return _trans.TransContinueStmt( Self )
  339. End Method
  340. End Type
  341. Type TIfStmt Extends TStmt
  342. Field expr:TExpr
  343. Field thenBlock:TBlockDecl
  344. Field elseBlock:TBlockDecl
  345. Method Create:TIfStmt( expr:TExpr,thenBlock:TBlockDecl,elseBlock:TBlockDecl, generated:Int = False )
  346. Self.expr=expr
  347. Self.thenBlock=thenBlock
  348. Self.elseBlock=elseBlock
  349. Self.generated = generated
  350. Return Self
  351. End Method
  352. Method OnCopy:TStmt( scope:TScopeDecl )
  353. Return New TIfStmt.Create( expr.Copy(),thenBlock.CopyBlock( scope ),elseBlock.CopyBlock( scope ), generated )
  354. End Method
  355. Method OnSemant()
  356. expr=expr.SemantAndCast( New TBoolType,CAST_EXPLICIT )
  357. thenBlock.Semant
  358. elseBlock.Semant
  359. End Method
  360. Method Trans$()
  361. Return _trans.TransIfStmt( Self )
  362. End Method
  363. End Type
  364. Type TLoopStmt Extends TStmt
  365. Field loopLabel:TLoopLabelDecl
  366. Field block:TBlockDecl
  367. End Type
  368. Type TWhileStmt Extends TLoopStmt
  369. Field expr:TExpr
  370. Method Create:TWhileStmt( expr:TExpr,block:TBlockDecl,loopLabel:TLoopLabelDecl, generated:Int = False )
  371. Self.expr=expr
  372. Self.block=block
  373. Self.loopLabel = loopLabel
  374. ' If loopLabel Then
  375. block.extra = Self
  376. ' End If
  377. Self.generated = generated
  378. Return Self
  379. End Method
  380. Method OnCopy:TStmt( scope:TScopeDecl )
  381. Return New TWhileStmt.Create( expr.Copy(),block.CopyBlock( scope ),TLoopLabelDecl(loopLabel.Copy()), generated )
  382. End Method
  383. Method OnSemant()
  384. expr=expr.SemantAndCast( New TBoolType,CAST_EXPLICIT )
  385. _loopnest:+1
  386. block.Semant
  387. _loopnest:-1
  388. End Method
  389. Method Trans$()
  390. Return _trans.TransWhileStmt( Self )
  391. End Method
  392. End Type
  393. Type TRepeatStmt Extends TLoopStmt
  394. Field expr:TExpr
  395. Method Create:TRepeatStmt( block:TBlockDecl,expr:TExpr,loopLabel:TLoopLabelDecl )
  396. Self.block=block
  397. Self.expr=expr
  398. Self.loopLabel=loopLabel
  399. ' If loopLabel Then
  400. block.extra = Self
  401. ' End If
  402. Return Self
  403. End Method
  404. Method OnCopy:TStmt( scope:TScopeDecl )
  405. Return New TRepeatStmt.Create( block.CopyBlock( scope ),expr.Copy(),TLoopLabelDecl(loopLabel.Copy()) )
  406. End Method
  407. Method OnSemant()
  408. _loopnest:+1
  409. block.Semant
  410. _loopnest:-1
  411. expr=expr.SemantAndCast( New TBoolType,CAST_EXPLICIT )
  412. End Method
  413. Method Trans$()
  414. Return _trans.TransRepeatStmt( Self )
  415. End Method
  416. End Type
  417. Type TForStmt Extends TLoopStmt
  418. Field init:TStmt 'assignment or local decl...
  419. Field expr:TExpr
  420. Field incr:TStmt 'assignment...
  421. Method Create:TForStmt( init:TStmt,expr:TExpr,incr:TStmt,block:TBlockDecl,loopLabel:TLoopLabelDecl )
  422. Self.init=init
  423. Self.expr=expr
  424. Self.incr=incr
  425. Self.block=block
  426. Self.loopLabel=loopLabel
  427. ' If loopLabel Then
  428. block.extra = Self
  429. ' End If
  430. Return Self
  431. End Method
  432. Method OnCopy:TStmt( scope:TScopeDecl )
  433. Return New TForStmt.Create( init.Copy( scope ),expr.Copy(),incr.Copy( scope ),block.CopyBlock( scope ),TLoopLabelDecl(loopLabel.Copy()) )
  434. End Method
  435. Method OnSemant()
  436. PushEnv block
  437. Local updateCastTypes:Int
  438. If TAssignStmt(init) And TIdentExpr(TAssignStmt(init).lhs) Then
  439. updateCastTypes = True
  440. End If
  441. init.Semant
  442. PopEnv
  443. If updateCastTypes Then
  444. ' ty in the casts are currently Null - we didn't know at the time of creating the statement, what the variable type was.
  445. ' Now we do, so we'll fill in the gaps.
  446. TCastExpr(TBinaryCompareExpr(expr).rhs).ty = TAssignStmt(init).lhs.exprType.Copy()
  447. TCastExpr(TBinaryMathExpr(TAssignStmt(incr).rhs).rhs).ty = TAssignStmt(init).lhs.exprType.Copy()
  448. End If
  449. expr=expr.Semant()
  450. ' for anything other than a const value, use a new local variable
  451. If Not TConstExpr(TBinaryCompareExpr(expr).rhs) Then
  452. Local tmp:TLocalDecl=New TLocalDecl.Create( "", TBinaryCompareExpr(expr).rhs.exprType,TBinaryCompareExpr(expr).rhs,, True )
  453. tmp.Semant()
  454. Local v:TVarExpr = New TVarExpr.Create( tmp )
  455. TBinaryCompareExpr(expr).rhs = New TStmtExpr.Create( New TDeclStmt.Create( tmp ), v ).Semant()
  456. End If
  457. _loopnest:+1
  458. block.Semant
  459. _loopnest:-1
  460. incr.Semant
  461. 'dodgy as hell! Reverse comparison for backward loops!
  462. Local assop:TAssignStmt=TAssignStmt( incr )
  463. Local addop:TBinaryExpr=TBinaryExpr( assop.rhs )
  464. Local stpval$=addop.rhs.Eval()
  465. If stpval.StartsWith( "-" )
  466. Local bexpr:TBinaryExpr=TBinaryExpr( expr )
  467. Select bexpr.op
  468. Case "<" bexpr.op=">"
  469. Case "<=" bexpr.op=">="
  470. End Select
  471. EndIf
  472. End Method
  473. Method Trans$()
  474. Return _trans.TransForStmt( Self )
  475. End Method
  476. End Type
  477. Type TAssertStmt Extends TStmt
  478. Field expr:TExpr
  479. Field elseExpr:TExpr
  480. Method Create:TAssertStmt( expr:TExpr, elseExpr:TExpr )
  481. Self.expr=expr
  482. Self.elseExpr=elseExpr
  483. Return Self
  484. End Method
  485. Method OnCopy:TStmt( scope:TScopeDecl )
  486. If elseExpr Then
  487. Return New TAssertStmt.Create( expr.Copy(),elseExpr.Copy() )
  488. Else
  489. Return New TAssertStmt.Create( expr.Copy(), Null )
  490. End If
  491. End Method
  492. Method OnSemant()
  493. expr=expr.SemantAndCast( New TBoolType,CAST_EXPLICIT )
  494. If elseExpr Then
  495. elseExpr = elseExpr.SemantAndCast(New TStringType,CAST_EXPLICIT)
  496. Else
  497. elseExpr = New TConstExpr.Create(New TStringType, "Assert failed")
  498. End If
  499. End Method
  500. Method Trans$()
  501. Return _trans.TransAssertStmt( Self )
  502. End Method
  503. End Type
  504. Type TEndStmt Extends TStmt
  505. Method Create:TEndStmt( )
  506. Return Self
  507. End Method
  508. Method OnCopy:TStmt( scope:TScopeDecl )
  509. Return New TEndStmt.Create( )
  510. End Method
  511. Method OnSemant()
  512. End Method
  513. Method Trans$()
  514. Return _trans.TransEndStmt( Self )
  515. End Method
  516. End Type
  517. Type TReleaseStmt Extends TStmt
  518. Field expr:TExpr
  519. Method Create:TReleaseStmt( expr:TExpr )
  520. Self.expr=expr
  521. Return Self
  522. End Method
  523. Method OnCopy:TStmt( scope:TScopeDecl )
  524. Return New TReleaseStmt.Create( expr.Copy() )
  525. End Method
  526. Method OnSemant()
  527. expr=expr.Semant()
  528. If Not TVarExpr( expr ) And Not TMemberVarExpr( expr) And Not TIndexExpr( expr ) err "Expression must be a variable"
  529. If Not TNumericType(expr.exprType) Err "Subexpression for release must be an integer variable"
  530. End Method
  531. Method Trans$()
  532. Return _trans.TransReleaseStmt( Self )
  533. End Method
  534. End Type
  535. Type TReadDataStmt Extends TStmt
  536. Field args:TExpr[]
  537. Method Create:TReadDataStmt( args:TExpr[] )
  538. Self.args=args
  539. Return Self
  540. End Method
  541. Method OnCopy:TStmt( scope:TScopeDecl )
  542. Return New TReadDataStmt.Create( TExpr.CopyArgs(args) )
  543. End Method
  544. Method OnSemant()
  545. If args Then
  546. For Local i:Int = 0 Until args.length
  547. args[i]=args[i].Semant()
  548. Local arg:TExpr = args[i]
  549. If Not TVarExpr(arg) And Not TMemberVarExpr(arg) And Not TIndexExpr(arg) And Not (TStmtExpr(arg) And TIndexExpr(TStmtExpr(arg).expr)) Then
  550. Err "Expression must be a variable"
  551. End If
  552. Next
  553. End If
  554. End Method
  555. Method Trans$()
  556. Return _trans.TransReadDataStmt( Self )
  557. End Method
  558. End Type
  559. Type TRestoreDataStmt Extends TStmt
  560. Field expr:TExpr
  561. Method Create:TRestoreDataStmt( expr:TExpr )
  562. Self.expr=expr
  563. Return Self
  564. End Method
  565. Method OnCopy:TStmt( scope:TScopeDecl )
  566. Return New TRestoreDataStmt.Create( expr.Copy() )
  567. End Method
  568. Method OnSemant()
  569. If Not TIdentExpr(expr) Then
  570. ' todo : better (more specific) error?
  571. Err "Expecting identifier"
  572. Else
  573. Local label:String = TIdentExpr(expr).ident
  574. TIdentExpr(expr).ident = "#" + TIdentExpr(expr).ident
  575. expr=expr.Semant()
  576. If Not expr Then
  577. Err "Label '" + label + "' not found"
  578. End If
  579. End If
  580. End Method
  581. Method Trans$()
  582. Return _trans.TransRestoreDataStmt( Self )
  583. End Method
  584. End Type
  585. Type TNativeStmt Extends TStmt
  586. Field raw:String
  587. Method Create:TNativeStmt( raw:String )
  588. Self.raw = raw
  589. Return Self
  590. End Method
  591. Method OnCopy:TStmt( scope:TScopeDecl )
  592. Return New TNativeStmt.Create( raw )
  593. End Method
  594. Method OnSemant()
  595. End Method
  596. Method Trans$()
  597. Return _trans.TransNativeStmt( Self )
  598. End Method
  599. End Type