expressions.jl 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. #======================================================
  2. AFFECTATION
  3. ======================================================#
  4. abstract type StarpuExpr end
  5. abstract type StarpuExprTyped <: StarpuExpr end
  6. struct StarpuExprTypedVar <: StarpuExprTyped
  7. name :: Symbol
  8. typ :: Type
  9. end
  10. struct StarpuExprTypedExpr <: StarpuExprTyped # TODO : remove typed expression ?
  11. expr :: StarpuExpr
  12. typ :: Type
  13. end
  14. struct StarpuExprAffect <: StarpuExpr
  15. var :: StarpuExpr
  16. expr :: StarpuExpr
  17. end
  18. struct StarpuExprBlock <: StarpuExpr
  19. exprs :: Vector{StarpuExpr}
  20. end
  21. struct StarpuExprCall <: StarpuExpr
  22. func :: Symbol
  23. args :: Vector{StarpuExpr}
  24. end
  25. struct StarpuExprCudaCall <: StarpuExpr
  26. ker_name :: Symbol
  27. nblocks :: StarpuExpr
  28. threads_per_block :: StarpuExpr
  29. args :: Vector{StarpuExpr}
  30. end
  31. struct StarpuExprField <: StarpuExpr
  32. left :: StarpuExpr
  33. field :: Symbol
  34. is_an_arrow :: Bool
  35. end
  36. struct StarpuExprInterval <: StarpuExpr
  37. start :: StarpuExpr
  38. step :: StarpuExpr
  39. stop :: StarpuExpr
  40. id :: String
  41. function StarpuExprInterval(start :: StarpuExpr, step :: StarpuExpr, stop :: StarpuExpr ; id :: String = rand_string())
  42. return new(start, step, stop, id)
  43. end
  44. end
  45. struct StarpuExprFor <: StarpuExpr
  46. iter :: Symbol
  47. set:: StarpuExprInterval
  48. body :: StarpuExpr
  49. is_independant :: Bool
  50. set_declarations :: Vector{StarpuExpr}
  51. end
  52. struct StarpuExprFunction <: StarpuExpr
  53. ret_type :: Type
  54. func :: Symbol
  55. args :: Vector{StarpuExprTypedVar}
  56. body :: StarpuExpr
  57. end
  58. struct StarpuExprIf <: StarpuExpr
  59. cond :: StarpuExpr
  60. then_statement :: StarpuExpr
  61. end
  62. struct StarpuExprIfElse <: StarpuExpr
  63. cond :: StarpuExpr
  64. then_statement :: StarpuExpr
  65. else_statement :: StarpuExpr
  66. end
  67. struct StarpuExprRef <: StarpuExpr
  68. ref :: StarpuExpr
  69. indexes :: Vector{StarpuExpr}
  70. end
  71. struct StarpuExprReturn <: StarpuExpr
  72. value :: StarpuExpr
  73. end
  74. struct StarpuExprBreak <: StarpuExpr
  75. end
  76. struct StarpuExprVar <: StarpuExpr
  77. name :: Symbol
  78. end
  79. struct StarpuExprInvalid <: StarpuExpr
  80. end
  81. struct StarpuExprValue <: StarpuExpr
  82. value :: Any
  83. end
  84. struct StarpuExprWhile <: StarpuExpr
  85. cond :: StarpuExpr
  86. body :: StarpuExpr
  87. end
  88. function starpu_parse_affect(x :: Expr)
  89. if (x.head != :(=))
  90. error("Invalid \"affectation\" expression")
  91. end
  92. var = starpu_parse(x.args[1])
  93. expr = starpu_parse(x.args[2])
  94. return StarpuExprAffect(var, expr)
  95. end
  96. function equals(x :: StarpuExprAffect, y :: StarpuExpr)
  97. if typeof(y) != StarpuExprAffect
  98. return false
  99. end
  100. return equals(x.var, y.var) && equals(x.expr, y.expr)
  101. end
  102. function print(io :: IO, x :: StarpuExprAffect ; indent = 0, restrict = false)
  103. print(io, x.var, indent = indent)
  104. print(io, " = ")
  105. need_to_transtyp = isa(x.var, StarpuExprTypedVar) # transtyping to avoid warning (or errors for cuda) during compilation time
  106. if need_to_transtyp
  107. print(io, "(", starpu_type_traduction(x.var.typ), ") (")
  108. end
  109. print(io, x.expr, indent = indent)
  110. if need_to_transtyp
  111. print(io, ")")
  112. end
  113. end
  114. function apply(func :: Function, expr :: StarpuExprAffect)
  115. var = apply(func, expr.var)
  116. new_expr = apply(func, expr.expr)
  117. return func(StarpuExprAffect(var, new_expr))
  118. end
  119. #======================================================
  120. BLOCK
  121. (series of instruction, not C variable scoping block)
  122. ======================================================#
  123. function is_unwanted(x :: Symbol)
  124. return false
  125. end
  126. function is_unwanted(x :: LineNumberNode)
  127. return true
  128. end
  129. function is_unwanted(x :: Expr)
  130. return false
  131. end
  132. function starpu_parse_block(x :: Expr)
  133. if (x.head != :block)
  134. error("Invalid \"block\" expression")
  135. end
  136. exprs = map(starpu_parse, filter(!is_unwanted, x.args))
  137. return StarpuExprBlock(exprs)
  138. end
  139. function print(io :: IO, x :: StarpuExprBlock ; indent = 0, restrict=false)
  140. for i in (1 : length(x.exprs))
  141. print(io, x.exprs[i], indent = indent)
  142. print(io, ";")
  143. if (i != length(x.exprs))
  144. print_newline(io, indent)
  145. end
  146. end
  147. end
  148. function apply(func :: Function, expr :: StarpuExprBlock)
  149. return func(StarpuExprBlock(map((x -> apply(func, x)), expr.exprs)))
  150. end
  151. #======================================================
  152. FUNCTION CALL
  153. ======================================================#
  154. function starpu_parse_call(x :: Expr)
  155. if (x.head != :call)
  156. error("Invalid \"call\" expression")
  157. end
  158. func = starpu_parse(x.args[1])
  159. if (x.args[1] == Symbol(":"))
  160. return starpu_parse_interval(x)
  161. end
  162. if (!isa(func, StarpuExprVar))
  163. error("Invalid \"call\" expression : function must be a variable")
  164. end
  165. args = map(starpu_parse, x.args[2:end])
  166. return StarpuExprCall(func.name, args)
  167. end
  168. starpu_infix_operators = (:(+), :(*), :(-), :(/), :(<), :(>), :(<=), :(>=), :(%))
  169. function print_prefix(io :: IO, x :: StarpuExprCall ; indent = 0, restrict=false)
  170. print(io, x.func, "(")
  171. for i in (1 : length(x.args))
  172. if (i != 1)
  173. print(io, ", ")
  174. end
  175. print(io, x.args[i], indent = indent)
  176. end
  177. print(io, ")")
  178. end
  179. function print_infix(io :: IO, x :: StarpuExprCall ; indent = 0,restrict=false)
  180. for i in (1 : length(x.args))
  181. if (i != 1)
  182. print(io, " ", x.func, " ")
  183. end
  184. print(io, "(")
  185. print(io, x.args[i], indent = indent)
  186. print(io, ")")
  187. end
  188. end
  189. function print(io :: IO, x :: StarpuExprCall ; indent = 0,restrict=false)
  190. if (length(x.args) >= 2 && x.func in starpu_infix_operators)
  191. print_infix(io, x, indent = indent)
  192. else
  193. print_prefix(io, x, indent = indent)
  194. end
  195. end
  196. function apply(func :: Function, expr :: StarpuExprCall)
  197. return func(StarpuExprCall(expr.func, map((x -> apply(func, x)), expr.args)))
  198. end
  199. #======================================================
  200. CUDA KERNEL CALL
  201. ======================================================#
  202. function print(io :: IO, expr :: StarpuExprCudaCall ; indent = 0,restrict=false)
  203. print_newline(io, indent)
  204. print(io, expr.ker_name)
  205. print_newline(io, indent + starpu_indent_size)
  206. print(io, "<<< ")
  207. print(io, expr.nblocks, indent = indent + 2 * starpu_indent_size)
  208. print(io, ", ")
  209. print(io, expr.threads_per_block, indent = indent + 2 * starpu_indent_size)
  210. print(io, ", 0, starpu_cuda_get_local_stream()")
  211. print_newline(io, indent + starpu_indent_size)
  212. print(io, ">>> (")
  213. for i in (1 : length(expr.args))
  214. if (i != 1)
  215. print(io, ", ")
  216. if (i % 4 == 1)
  217. print_newline(io, indent + 2 * starpu_indent_size + 1)
  218. end
  219. end
  220. print(io, expr.args[i], indent = indent + 2 * starpu_indent_size)
  221. end
  222. print(io, ");")
  223. print_newline(io, indent)
  224. end
  225. function apply(func :: Function, expr :: StarpuExprCudaCall)
  226. nblocks = func(expr.nblocks)
  227. threads_per_block = func(expr.threads_per_block)
  228. args = map((x -> apply(func, x)), expr.args)
  229. return StarpuExprCudaCall(expr.ker_name, nblocks, threads_per_block, args)
  230. end
  231. #======================================================
  232. STRUCTURE FIELDS
  233. ======================================================#
  234. function starpu_parse_field(x :: Expr)
  235. if x.head != :(.) || length(x.args) != 2
  236. error("Invalid parsing of dot expression")
  237. end
  238. left = starpu_parse(x.args[1])
  239. if (!isa(x.args[2], QuoteNode) || !isa(x.args[2].value, Symbol))
  240. error("Invalid parsing of dot expression")
  241. end
  242. return StarpuExprField(left, x.args[2].value, false)
  243. end
  244. function print(io :: IO, x :: StarpuExprField ; indent = 0,restrict=false)
  245. print(io, "(")
  246. print(io, x.left, indent = indent)
  247. print(io, ")", x.is_an_arrow ? "->" : '.', x.field)
  248. end
  249. function apply(func :: Function, expr :: StarpuExprField)
  250. return func(StarpuExprField(func(expr.left), expr.field, expr.is_an_arrow))
  251. end
  252. #======================================================
  253. FOR LOOPS
  254. ======================================================#
  255. function starpu_parse_for(x :: Expr; is_independant = false)
  256. if (x.head != :for)
  257. error("Invalid \"for\" expression")
  258. end
  259. affect = x.args[1]
  260. if (affect.head != :(=))
  261. error("Invalid \"for\" iterator affectation")
  262. end
  263. iter = starpu_parse(affect.args[1])
  264. if (!isa(iter, StarpuExprVar))
  265. error("Invalid \"for\" iterator")
  266. end
  267. set = starpu_parse(affect.args[2])
  268. if (!isa(set, StarpuExprInterval))
  269. error("Set of values in \"for\" loop must be an interval")
  270. end
  271. body = starpu_parse(x.args[2])
  272. return StarpuExprFor(iter.name, set, body, is_independant, StarpuExpr[])
  273. end
  274. function print(io :: IO, x :: StarpuExprFor ; indent = 0,restrict=false)
  275. print_newline(io, indent)
  276. print(io, StarpuExprBlock(x.set_declarations), indent = indent)
  277. id = x.set.id
  278. start = "start_" * id
  279. stop = "stop_" * id
  280. step = "step_" * id
  281. dim = "dim_" * id
  282. iter = "iter_" * id
  283. print_newline(io, indent, 2)
  284. if isa(x.set.step, StarpuExprValue)
  285. print(io, "for ($(x.iter) = $start ; ")
  286. comparison_op = (x.set.step.value >= 0) ? "<=" : ">="
  287. print(io, "$(x.iter) $comparison_op $stop ; ")
  288. print(io, "$(x.iter) += $(x.set.step.value))")
  289. else
  290. print(io, "for ($iter = 0, $(x.iter) = $start ; ")
  291. print(io, "$iter < $dim ; ")
  292. print(io, "$iter += 1, $(x.iter) += $step)")
  293. end
  294. print_newline(io, indent)
  295. print(io, "{")
  296. print_newline(io, indent + starpu_indent_size)
  297. print(io, x.body, indent = indent + starpu_indent_size)
  298. print_newline(io, indent)
  299. print(io, "}")
  300. print_newline(io, indent)
  301. end
  302. function apply(func :: Function, expr :: StarpuExprFor)
  303. set_declarations = map( (x -> apply(func, x)), expr.set_declarations)
  304. set = apply(func, expr.set)
  305. body = apply(func, expr.body)
  306. return func(StarpuExprFor(expr.iter, set, body, expr.is_independant, set_declarations))
  307. end
  308. #======================================================
  309. FUNCTION DECLARATION
  310. ======================================================#
  311. function starpu_parse_function(x :: Expr)
  312. if (x.head != :function)
  313. error("Invalid \"function\" expression")
  314. end
  315. typed_decl = starpu_parse(x.args[1])
  316. if (!isa(typed_decl, StarpuExprTypedExpr))
  317. error("Invalid \"function\" prototype : a return type must me explicited")
  318. end
  319. prototype = typed_decl.expr
  320. if (!isa(prototype, StarpuExprCall))
  321. error("Invalid \"function\" prototype")
  322. end
  323. arg_list = StarpuExprTypedVar[]
  324. for type_arg in prototype.args
  325. if (!isa(type_arg, StarpuExprTypedVar))
  326. error("Invalid \"function\" argument list")
  327. end
  328. push!(arg_list, type_arg)
  329. end
  330. body = starpu_parse(x.args[2])
  331. return StarpuExprFunction(typed_decl.typ, prototype.func, arg_list, body)
  332. end
  333. function print(io :: IO, x :: StarpuExprFunction ; indent = 0,restrict=false)
  334. print(io, starpu_type_traduction(x.ret_type), " ")
  335. print(io, x.func, '(')
  336. for i in (1 : length(x.args))
  337. if (i != 1)
  338. print(io, ", ")
  339. if (i % 4 == 1)
  340. print_newline(io, indent + starpu_indent_size + length(String(x.func)) + 13)
  341. end
  342. end
  343. print(io, x.args[i], indent = indent + starpu_indent_size, restrict = true)
  344. end
  345. print(io, ")")
  346. print_newline(io, indent)
  347. print(io, "{")
  348. print_newline(io, indent + starpu_indent_size)
  349. print(io, x.body, indent = indent + starpu_indent_size)
  350. print_newline(io, indent)
  351. print(io, "}\n\n")
  352. print_newline(io, indent)
  353. end
  354. function apply(func :: Function, expr :: StarpuExprFunction)
  355. args = map((x -> apply(func, x)), expr.args)
  356. body = apply(func, expr.body)
  357. return func(StarpuExprFunction(expr.ret_type, expr.func, args, body))
  358. end
  359. #======================================================
  360. IF STATEMENT
  361. ======================================================#
  362. function starpu_parse_if(x :: Expr)
  363. if (x.head != :if)
  364. error("Invalid \"if\" expression")
  365. end
  366. len = length(x.args)
  367. if (len < 2)
  368. error("Invalid \"if\" statement")
  369. end
  370. cond = starpu_parse(x.args[1])
  371. then_statement = starpu_parse(x.args[2])
  372. if (len == 2)
  373. return StarpuExprIf(cond, then_statement)
  374. end
  375. else_statement = starpu_parse(x.args[3])
  376. return StarpuExprIfElse(cond, then_statement, else_statement)
  377. end
  378. function print(io :: IO, x :: Union{StarpuExprIf, StarpuExprIfElse}; indent = 0,restrict=false)
  379. print_newline(io, indent)
  380. print(io, "if (")
  381. print(io, x.cond, indent = indent + starpu_indent_size)
  382. print(io, ")")
  383. print_newline(io, indent)
  384. print(io, "{")
  385. print_newline(io, indent + starpu_indent_size)
  386. print(io, x.then_statement, indent = indent + starpu_indent_size)
  387. print_newline(io, indent)
  388. print(io, "}")
  389. if (!isa(x, StarpuExprIfElse))
  390. return
  391. end
  392. print(io, " else")
  393. print_newline(io, indent)
  394. print(io, "{")
  395. print_newline(io, indent + starpu_indent_size)
  396. print(io, x.else_statement, indent = indent + starpu_indent_size)
  397. print_newline(io, indent)
  398. print(io, "}")
  399. print_newline(io, indent)
  400. end
  401. function apply(func :: Function, expr :: StarpuExprIf)
  402. cond = apply(func, expr.cond)
  403. then_statement = apply(func, expr.then_statement)
  404. return func(StarpuExprIf(cond, then_statement))
  405. end
  406. function apply(func :: Function, expr :: StarpuExprIfElse)
  407. cond = apply(func, expr.cond)
  408. then_statement = apply(func, expr.then_statement)
  409. else_statement = apply(func, expr.else_statement)
  410. return func(StarpuExprIfElse(cond, then_statement, else_statement))
  411. end
  412. #======================================================
  413. INTERVALS
  414. ======================================================#
  415. function starpu_parse_interval(x :: Expr)
  416. if (x.head != :(call))
  417. error("Invalid \"interval\" expression")
  418. end
  419. start = starpu_parse(x.args[2])
  420. steop = starpu_parse(x.args[3])
  421. if (length(x.args) == 3)
  422. return StarpuExprInterval(start, StarpuExprValue(1), steop)
  423. end
  424. stop = starpu_parse(x.args[4])
  425. return StarpuExprInterval(start, steop, stop)
  426. end
  427. function apply(func :: Function, expr :: StarpuExprInterval)
  428. start = apply(func, expr.start)
  429. step = apply(func, expr.step)
  430. stop = apply(func, expr.stop)
  431. return func(StarpuExprInterval(start, step, stop, id = expr.id))
  432. end
  433. #======================================================
  434. ARRAYS AND REFERENCES
  435. ======================================================#
  436. function starpu_parse_ref(x :: Expr)
  437. if (x.head != :ref)
  438. error("Invalid \"reference\" expression")
  439. end
  440. ref = starpu_parse(x.args[1])
  441. indexes = map(starpu_parse, x.args[2:end])
  442. #=
  443. StarpuExpr[]
  444. for i in (2 : length(x.args))
  445. push!(indexes, starpu_parse(x.args[i]))
  446. end=#
  447. return StarpuExprRef(ref, indexes)
  448. end
  449. function equals(x :: StarpuExprRef, y :: StarpuExpr)
  450. if typeof(y) != StarpuExprRef
  451. return false
  452. end
  453. if !equals(x.ref, y.ref) || length(x.indexes) != length(y.indexes)
  454. return false
  455. end
  456. return all(map(equals, x.indexes, y.indexes))
  457. end
  458. function print(io :: IO, x :: StarpuExprRef ; indent = 0,restrict=false)
  459. print(io, x.ref, indent = indent)
  460. for i in (1 : length(x.indexes))
  461. print(io, "[")
  462. print(io, x.indexes[i], indent = indent)
  463. print(io, "]")
  464. end
  465. end
  466. function apply(func :: Function, expr :: StarpuExprRef)
  467. ref = apply(func, expr.ref)
  468. indexes = map((x -> apply(func, x)), expr.indexes)
  469. return func(StarpuExprRef(ref, indexes))
  470. end
  471. #======================================================
  472. BREAK EXPRESSION
  473. ======================================================#
  474. function starpu_parse_break(x :: Expr)
  475. if (x.head != :break)
  476. error("Invalid \"break\" expression")
  477. end
  478. return StarpuExprBreak()
  479. end
  480. function print(io :: IO, x :: StarpuExprBreak ; indent = 0)
  481. print(io, "break")
  482. end
  483. function apply(func :: Function, expr :: StarpuExprBreak)
  484. return func(StarpuExprBreak())
  485. end
  486. #======================================================
  487. RETURN EXPRESSION
  488. ======================================================#
  489. function starpu_parse_return(x :: Expr)
  490. if (x.head != :return)
  491. error("Invalid \"return\" expression")
  492. end
  493. value = starpu_parse(x.args[1])
  494. # Remove type associated to a single, for a return
  495. # allows matching with ExprVar
  496. if (isa(value, StarpuExprTypedVar))
  497. value = StarpuExprVar(value.name)
  498. end
  499. return StarpuExprReturn(value)
  500. end
  501. function print(io :: IO, x :: StarpuExprReturn ; indent = 0,restrict=false)
  502. print(io, "return ")
  503. print(io, x.value, indent = indent)
  504. end
  505. function apply(func :: Function, expr :: StarpuExprReturn)
  506. return func(StarpuExprReturn(apply(func, expr.value)))
  507. end
  508. function apply(func :: Function, expr :: StarpuExpr)
  509. return func(expr)
  510. end
  511. print(io :: IO, x :: StarpuExprVar ; indent = 0) = print(io, x.name)
  512. function print(io :: IO, x :: StarpuExprValue ; indent = 0,restrict=false)
  513. value = x.value
  514. if value == nothing
  515. return
  516. end
  517. if isa(value, AbstractString)
  518. print(io, '"', value, '"')
  519. return
  520. end
  521. if isa(value, Char)
  522. print(io, '\'', value, '\'')
  523. return
  524. end
  525. print(io, value)
  526. end
  527. print(io :: IO, x :: StarpuExprInvalid ; indent = 0) = print(io, "INVALID")
  528. function starpu_parse(raw_value :: Any)
  529. return StarpuExprValue(raw_value)
  530. end
  531. function starpu_parse(sym :: Symbol)
  532. return StarpuExprVar(sym)
  533. end
  534. #======================================================
  535. TYPED EXPRESSION
  536. ======================================================#
  537. function starpu_parse_typed(x :: Expr)
  538. if (x.head != :(::))
  539. error("Invalid type assigned expression")
  540. end
  541. expr = starpu_parse(x.args[1])
  542. typ = nothing
  543. try
  544. typ = eval(x.args[2]) :: Type
  545. catch
  546. print(x.args[2])
  547. error("Invalid type in type assigned expression")
  548. end
  549. if (isa(expr, StarpuExprVar))
  550. return StarpuExprTypedVar(expr.name, typ)
  551. end
  552. return StarpuExprTypedExpr(expr, typ)
  553. end
  554. starpu_type_traduction_dict = Dict(
  555. Int32 => "int32_t",
  556. UInt32 => "uint32_t",
  557. Float32 => "float",
  558. Int64 => "int64_t",
  559. UInt64 => "uint64_t",
  560. Float64 => "double",
  561. Nothing => "void"
  562. )
  563. function starpu_type_traduction(x)
  564. if x <: Array
  565. return starpu_type_traduction_array(x)
  566. end
  567. if x <: Ptr
  568. return starpu_type_traduction(eltype(x)) * "*"
  569. end
  570. return starpu_type_traduction_dict[x]
  571. end
  572. function starpu_type_traduction_array(x :: Type{Array{T,N}}) where {T,N}
  573. output = starpu_type_traduction(T)
  574. for i in (1 : N)
  575. output *= "*"
  576. end
  577. return output
  578. end
  579. function print(io :: IO, x :: StarpuExprTyped ; indent = 0,restrict=false)
  580. if (isa(x, StarpuExprTypedVar))
  581. print(io,starpu_type_traduction(x.typ), " ")
  582. #if (restrict)
  583. # print(io,"restrict ");
  584. #end
  585. print(io, x.name)
  586. else
  587. print(io, x.expr, indent = indent)
  588. end
  589. end
  590. function apply(func :: Function, expr :: StarpuExprTypedExpr)
  591. new_expr = apply(func, expr.expr)
  592. return func(StarpuExprTypedExpr(new_expr, expr.typ))
  593. end
  594. #======================================================
  595. While loop
  596. ======================================================#
  597. function starpu_parse_while(x :: Expr)
  598. if (x.head != :while)
  599. error("Invalid \"while\" loop")
  600. end
  601. len = length(x.args)
  602. if (len < 2)
  603. error("Invalid \"while\" loop")
  604. end
  605. cond = starpu_parse(x.args[1])
  606. body = starpu_parse(x.args[2])
  607. return StarpuExprWhile(cond, body)
  608. end
  609. function print(io :: IO, x :: StarpuExprWhile ; indent = 0)
  610. print_newline(io, indent)
  611. print(io, "while (")
  612. print(io, x.cond, indent = indent + starpu_indent_size)
  613. print(io, ")")
  614. print_newline(io, indent)
  615. print(io, "{")
  616. print_newline(io, indent + starpu_indent_size)
  617. print(io, x.body, indent = indent + starpu_indent_size)
  618. print_newline(io, indent)
  619. print(io, "}")
  620. print_newline(io, indent)
  621. end
  622. function apply(func :: Function, expr :: StarpuExprWhile)
  623. cond = apply(func, expr.cond)
  624. body = apply(func, expr.body)
  625. return func(StarpuExprWhile(cond, body))
  626. end