cbuilderbase.nim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import ropes, int128
  2. type
  3. Snippet* = string
  4. Builder* = object
  5. buf*: string
  6. indents*: int
  7. template newBuilder*(s: string): Builder =
  8. Builder(buf: s)
  9. proc extract*(builder: Builder): Snippet =
  10. builder.buf
  11. proc add*(builder: var Builder, s: string) =
  12. builder.buf.add(s)
  13. proc add*(builder: var Builder, s: char) =
  14. builder.buf.add(s)
  15. proc addNewline*(builder: var Builder) =
  16. builder.add('\n')
  17. for i in 0 ..< builder.indents:
  18. builder.add('\t')
  19. proc addLineEnd*(builder: var Builder, s: string) =
  20. builder.add(s)
  21. builder.addNewline()
  22. proc addLineEndIndent*(builder: var Builder, s: string) =
  23. inc builder.indents
  24. builder.add(s)
  25. builder.addNewline()
  26. proc addDedent*(builder: var Builder, s: string) =
  27. if builder.buf.len > 0 and builder.buf[^1] == '\t':
  28. builder.buf.setLen(builder.buf.len - 1)
  29. builder.add(s)
  30. dec builder.indents
  31. proc addLineEndDedent*(builder: var Builder, s: string) =
  32. builder.addDedent(s)
  33. builder.addNewline()
  34. proc addLineComment*(builder: var Builder, comment: string) =
  35. # probably no-op on nifc
  36. builder.add("// ")
  37. builder.add(comment)
  38. builder.addNewline()
  39. proc addIntValue*(builder: var Builder, val: int) =
  40. builder.buf.addInt(val)
  41. proc addIntValue*(builder: var Builder, val: int64) =
  42. builder.buf.addInt(val)
  43. proc addIntValue*(builder: var Builder, val: uint64) =
  44. builder.buf.addInt(val)
  45. proc addIntValue*(builder: var Builder, val: Int128) =
  46. builder.buf.addInt128(val)
  47. template cIntValue*(val: int): Snippet = $val
  48. template cIntValue*(val: int64): Snippet = $val
  49. template cIntValue*(val: uint64): Snippet = $val
  50. template cIntValue*(val: Int128): Snippet = $val
  51. template cUintValue*(val: uint): Snippet = $val & "U"
  52. import std/formatfloat
  53. proc addFloatValue*(builder: var Builder, val: float) =
  54. builder.buf.addFloat(val)
  55. template cFloatValue*(val: float): Snippet = $val
  56. proc addInt64Literal*(result: var Builder; i: BiggestInt) =
  57. if i > low(int64):
  58. result.add "IL64($1)" % [rope(i)]
  59. else:
  60. result.add "(IL64(-9223372036854775807) - IL64(1))"
  61. proc addUint64Literal*(result: var Builder; i: uint64) =
  62. result.add rope($i & "ULL")
  63. proc addIntLiteral*(result: var Builder; i: BiggestInt) =
  64. if i > low(int32) and i <= high(int32):
  65. result.addIntValue(i)
  66. elif i == low(int32):
  67. # Nim has the same bug for the same reasons :-)
  68. result.add "(-2147483647 -1)"
  69. elif i > low(int64):
  70. result.add "IL64($1)" % [rope(i)]
  71. else:
  72. result.add "(IL64(-9223372036854775807) - IL64(1))"
  73. proc addIntLiteral*(result: var Builder; i: Int128) =
  74. addIntLiteral(result, toInt64(i))
  75. proc cInt64Literal*(i: BiggestInt): Snippet =
  76. if i > low(int64):
  77. result = "IL64($1)" % [rope(i)]
  78. else:
  79. result = "(IL64(-9223372036854775807) - IL64(1))"
  80. proc cUint64Literal*(i: uint64): Snippet =
  81. result = $i & "ULL"
  82. proc cIntLiteral*(i: BiggestInt): Snippet =
  83. if i > low(int32) and i <= high(int32):
  84. result = rope(i)
  85. elif i == low(int32):
  86. # Nim has the same bug for the same reasons :-)
  87. result = "(-2147483647 -1)"
  88. elif i > low(int64):
  89. result = "IL64($1)" % [rope(i)]
  90. else:
  91. result = "(IL64(-9223372036854775807) - IL64(1))"
  92. proc cIntLiteral*(i: Int128): Snippet =
  93. result = cIntLiteral(toInt64(i))
  94. const
  95. NimInt* = "NI"
  96. NimInt8* = "NI8"
  97. NimInt16* = "NI16"
  98. NimInt32* = "NI32"
  99. NimInt64* = "NI64"
  100. CInt* = "int"
  101. NimUint* = "NU"
  102. NimUint8* = "NU8"
  103. NimUint16* = "NU16"
  104. NimUint32* = "NU32"
  105. NimUint64* = "NU64"
  106. NimFloat* = "NF"
  107. NimFloat32* = "NF32"
  108. NimFloat64* = "NF64"
  109. NimFloat128* = "NF128" # not actually defined
  110. NimNan* = "NAN"
  111. NimInf* = "INF"
  112. NimBool* = "NIM_BOOL"
  113. NimTrue* = "NIM_TRUE"
  114. NimFalse* = "NIM_FALSE"
  115. NimChar* = "NIM_CHAR"
  116. CChar* = "char"
  117. NimCstring* = "NCSTRING"
  118. NimNil* = "NIM_NIL"
  119. CNil* = "NULL"
  120. NimStrlitFlag* = "NIM_STRLIT_FLAG"
  121. CVoid* = "void"
  122. CPointer* = "void*"
  123. CConstPointer* = "NIM_CONST void*"
  124. proc cIntType*(bits: BiggestInt): Snippet =
  125. "NI" & $bits
  126. proc cUintType*(bits: BiggestInt): Snippet =
  127. "NU" & $bits
  128. type
  129. IfBuilderState* = enum
  130. WaitingIf, WaitingElseIf, InBlock
  131. IfBuilder* = object
  132. state*: IfBuilderState