cbuilderstmts.nim 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. template addAssignmentWithValue(builder: var Builder, lhs: Snippet, valueBody: typed) =
  2. builder.add(lhs)
  3. builder.add(" = ")
  4. valueBody
  5. builder.add(";\n")
  6. template addFieldAssignmentWithValue(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
  7. builder.add(lhs)
  8. builder.add("." & name & " = ")
  9. valueBody
  10. builder.add(";\n")
  11. template addAssignment(builder: var Builder, lhs, rhs: Snippet) =
  12. builder.addAssignmentWithValue(lhs):
  13. builder.add(rhs)
  14. template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
  15. builder.addFieldAssignmentWithValue(lhs, name):
  16. builder.add(rhs)
  17. template addMutualFieldAssignment(builder: var Builder, lhs, rhs: Snippet, name: string) =
  18. builder.addFieldAssignmentWithValue(lhs, name):
  19. builder.add(rhs)
  20. builder.add("." & name)
  21. template addAssignment(builder: var Builder, lhs: Snippet, rhs: int | int64 | uint64 | Int128) =
  22. builder.addAssignmentWithValue(lhs):
  23. builder.addIntValue(rhs)
  24. template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: int | int64 | uint64 | Int128) =
  25. builder.addFieldAssignmentWithValue(lhs, name):
  26. builder.addIntValue(rhs)
  27. template addDerefFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
  28. builder.add(lhs)
  29. builder.add("->" & name & " = ")
  30. builder.add(rhs)
  31. builder.add(";\n")
  32. template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snippet, rhs: Snippet) =
  33. builder.add(lhs)
  34. builder.add("[" & index & "] = ")
  35. builder.add(rhs)
  36. builder.add(";\n")
  37. template addStmt(builder: var Builder, stmtBody: typed) =
  38. ## makes an expression built by `stmtBody` into a statement
  39. stmtBody
  40. builder.add(";\n")
  41. proc addCallStmt(builder: var Builder, callee: Snippet, args: varargs[Snippet]) =
  42. builder.addStmt():
  43. builder.addCall(callee, args)
  44. # XXX blocks need indent tracker in `Builder` object
  45. template addSingleIfStmt(builder: var Builder, cond: Snippet, body: typed) =
  46. builder.add("if (")
  47. builder.add(cond)
  48. builder.add(") {\n")
  49. body
  50. builder.add("}\n")
  51. template addSingleIfStmtWithCond(builder: var Builder, condBody: typed, body: typed) =
  52. builder.add("if (")
  53. condBody
  54. builder.add(") {\n")
  55. body
  56. builder.add("}\n")
  57. type IfStmt = object
  58. needsElse: bool
  59. template addIfStmt(builder: var Builder, stmt: out IfStmt, body: typed) =
  60. stmt = IfStmt(needsElse: false)
  61. body
  62. builder.add("\n")
  63. template addElifBranch(builder: var Builder, stmt: var IfStmt, cond: Snippet, body: typed) =
  64. if stmt.needsElse:
  65. builder.add(" else ")
  66. else:
  67. stmt.needsElse = true
  68. builder.add("if (")
  69. builder.add(cond)
  70. builder.add(") {\n")
  71. body
  72. builder.add("}")
  73. template addElseBranch(builder: var Builder, stmt: var IfStmt, body: typed) =
  74. assert stmt.needsElse
  75. builder.add(" else {\n")
  76. body
  77. builder.add("}")
  78. proc addForRangeHeader(builder: var Builder, i, start, bound: Snippet, inclusive: bool = false) =
  79. builder.add("for (")
  80. builder.add(i)
  81. builder.add(" = ")
  82. builder.add(start)
  83. builder.add("; ")
  84. builder.add(i)
  85. if inclusive:
  86. builder.add(" <= ")
  87. else:
  88. builder.add(" < ")
  89. builder.add(bound)
  90. builder.add("; ")
  91. builder.add(i)
  92. builder.add("++) {\n")
  93. template addForRangeExclusive(builder: var Builder, i, start, bound: Snippet, body: typed) =
  94. addForRangeHeader(builder, i, start, bound, false)
  95. body
  96. builder.add("}\n")
  97. template addForRangeInclusive(builder: var Builder, i, start, bound: Snippet, body: typed) =
  98. addForRangeHeader(builder, i, start, bound, true)
  99. body
  100. builder.add("}\n")
  101. template addScope(builder: var Builder, body: typed) =
  102. builder.add("{")
  103. body
  104. builder.add("\t}")
  105. proc addLabel(builder: var Builder, name: TLabel) =
  106. builder.add(name)
  107. builder.add(": ;\n")
  108. proc addReturn(builder: var Builder) =
  109. builder.add("return;\n")
  110. proc addReturn(builder: var Builder, value: string) =
  111. builder.add("return ")
  112. builder.add(value)
  113. builder.add(";\n")
  114. template addGoto(builder: var Builder, label: TLabel) =
  115. builder.add("goto ")
  116. builder.add(label)
  117. builder.add(";\n")
  118. template addIncr(builder: var Builder, val: Snippet) =
  119. builder.add(val)
  120. builder.add("++;\n")
  121. template addDecr(builder: var Builder, val: Snippet) =
  122. builder.add(val)
  123. builder.add("--;\n")