Skip to content

Commit 658c9da

Browse files
authored
cbuilder: ccgexprs sweep part 1, basic if stmts (#24381)
Most of what ccgexprs uses is now ported to cbuilder, so this PR makes around ~25% of ccgexprs use it, along with adding `if` stmts (no `while`/`switch` and `for` which is only used as `for (tmp = a; tmp < b; tmp++)`). The `if` builder does not add indents for blocks since we can't make `Builder` an object yet rather than an alias to `string`, this will likely be one of the last refactors. Somewhat unrelated but `ccgtypes` is not ready yet because proc signatures are not implemented.
1 parent 5e56f0a commit 658c9da

File tree

6 files changed

+483
-322
lines changed

6 files changed

+483
-322
lines changed

compiler/cbuilderbase.nim

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,50 @@ import std/formatfloat
2727
proc addFloatValue(builder: var Builder, val: float) =
2828
builder.addFloat(val)
2929

30-
proc cFloatValue(val: float): Snippet =
31-
result = ""
32-
result.addFloat(val)
30+
template cFloatValue(val: float): Snippet = $val
31+
32+
proc int64Literal(i: BiggestInt; result: var Builder) =
33+
if i > low(int64):
34+
result.add "IL64($1)" % [rope(i)]
35+
else:
36+
result.add "(IL64(-9223372036854775807) - IL64(1))"
37+
38+
proc uint64Literal(i: uint64; result: var Builder) =
39+
result.add rope($i & "ULL")
40+
41+
proc intLiteral(i: BiggestInt; result: var Builder) =
42+
if i > low(int32) and i <= high(int32):
43+
result.addIntValue(i)
44+
elif i == low(int32):
45+
# Nim has the same bug for the same reasons :-)
46+
result.add "(-2147483647 -1)"
47+
elif i > low(int64):
48+
result.add "IL64($1)" % [rope(i)]
49+
else:
50+
result.add "(IL64(-9223372036854775807) - IL64(1))"
51+
52+
proc intLiteral(i: Int128; result: var Builder) =
53+
intLiteral(toInt64(i), result)
54+
55+
proc cInt64Literal(i: BiggestInt): Snippet =
56+
if i > low(int64):
57+
result = "IL64($1)" % [rope(i)]
58+
else:
59+
result = "(IL64(-9223372036854775807) - IL64(1))"
60+
61+
proc cUint64Literal(i: uint64): Snippet =
62+
result = $i & "ULL"
63+
64+
proc cIntLiteral(i: BiggestInt): Snippet =
65+
if i > low(int32) and i <= high(int32):
66+
result = rope(i)
67+
elif i == low(int32):
68+
# Nim has the same bug for the same reasons :-)
69+
result = "(-2147483647 -1)"
70+
elif i > low(int64):
71+
result = "IL64($1)" % [rope(i)]
72+
else:
73+
result = "(IL64(-9223372036854775807) - IL64(1))"
74+
75+
proc cIntLiteral(i: Int128): Snippet =
76+
result = cIntLiteral(toInt64(i))

compiler/cbuilderexprs.nim

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22
# XXX add stuff like NI, NIM_NIL as constants
33

44
proc constType(t: Snippet): Snippet =
5+
# needs manipulation of `t` in nifc
56
"NIM_CONST " & t
67

8+
proc constPtrType(t: Snippet): Snippet =
9+
t & "* NIM_CONST"
10+
11+
proc ptrConstType(t: Snippet): Snippet =
12+
"NIM_CONST " & t & "*"
13+
714
proc ptrType(t: Snippet): Snippet =
815
t & "*"
916

@@ -26,6 +33,11 @@ proc wrapPar(value: Snippet): Snippet =
2633
# used for expression group, no-op on sexp
2734
"(" & value & ")"
2835

36+
proc removeSinglePar(value: Snippet): Snippet =
37+
# removes a single paren layer expected to exist, to silence Wparentheses-equality
38+
assert value[0] == '(' and value[^1] == ')'
39+
value[1..^2]
40+
2941
template addCast(builder: var Builder, typ: Snippet, valueBody: typed) =
3042
## adds a cast to `typ` with value built by `valueBody`
3143
builder.add "(("
@@ -75,16 +87,26 @@ template addCall(builder: var Builder, call: out CallBuilder, callee: Snippet, b
7587
body
7688
finishCallBuilder(builder, call)
7789

78-
proc addNullaryCall(builder: var Builder, callee: Snippet) =
79-
builder.add(callee)
80-
builder.add("()")
81-
82-
proc addUnaryCall(builder: var Builder, callee: Snippet, arg: Snippet) =
90+
proc addCall(builder: var Builder, callee: Snippet, args: varargs[Snippet]) =
8391
builder.add(callee)
8492
builder.add("(")
85-
builder.add(arg)
93+
if args.len != 0:
94+
builder.add(args[0])
95+
for i in 1 ..< args.len:
96+
builder.add(", ")
97+
builder.add(args[i])
8698
builder.add(")")
8799

100+
proc cCall(callee: Snippet, args: varargs[Snippet]): Snippet =
101+
result = callee
102+
result.add("(")
103+
if args.len != 0:
104+
result.add(args[0])
105+
for i in 1 ..< args.len:
106+
result.add(", ")
107+
result.add(args[i])
108+
result.add(")")
109+
88110
proc addSizeof(builder: var Builder, val: Snippet) =
89111
builder.add("sizeof(")
90112
builder.add(val)

compiler/cbuilderstmts.nim

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,94 @@
1-
template addAssignment(builder: var Builder, lhs: Snippet, valueBody: typed) =
1+
template addAssignmentWithValue(builder: var Builder, lhs: Snippet, valueBody: typed) =
22
builder.add(lhs)
33
builder.add(" = ")
44
valueBody
55
builder.add(";\n")
66

7-
template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
7+
template addFieldAssignmentWithValue(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
88
builder.add(lhs)
99
builder.add("." & name & " = ")
1010
valueBody
1111
builder.add(";\n")
1212

13-
template addDerefFieldAssignment(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
13+
template addAssignment(builder: var Builder, lhs, rhs: Snippet) =
14+
builder.addAssignmentWithValue(lhs):
15+
builder.add(rhs)
16+
17+
template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
18+
builder.addFieldAssignmentWithValue(lhs, name):
19+
builder.add(rhs)
20+
21+
template addMutualFieldAssignment(builder: var Builder, lhs, rhs: Snippet, name: string) =
22+
builder.addFieldAssignmentWithValue(lhs, name):
23+
builder.add(rhs)
24+
builder.add("." & name)
25+
26+
template addAssignment(builder: var Builder, lhs: Snippet, rhs: int | int64 | uint64 | Int128) =
27+
builder.addAssignmentWithValue(lhs):
28+
builder.addIntValue(rhs)
29+
30+
template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: int | int64 | uint64 | Int128) =
31+
builder.addFieldAssignmentWithValue(lhs, name):
32+
builder.addIntValue(rhs)
33+
34+
template addDerefFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
1435
builder.add(lhs)
1536
builder.add("->" & name & " = ")
16-
valueBody
37+
builder.add(rhs)
1738
builder.add(";\n")
1839

19-
template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snippet, valueBody: typed) =
40+
template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snippet, rhs: Snippet) =
2041
builder.add(lhs)
2142
builder.add("[" & index & "] = ")
22-
valueBody
43+
builder.add(rhs)
2344
builder.add(";\n")
2445

2546
template addStmt(builder: var Builder, stmtBody: typed) =
2647
## makes an expression built by `stmtBody` into a statement
2748
stmtBody
2849
builder.add(";\n")
50+
51+
proc addCallStmt(builder: var Builder, callee: Snippet, args: varargs[Snippet]) =
52+
builder.addStmt():
53+
builder.addCall(callee, args)
54+
55+
# XXX blocks need indent tracker in `Builder` object
56+
57+
template addSingleIfStmt(builder: var Builder, cond: Snippet, body: typed) =
58+
builder.add("if (")
59+
builder.add(cond)
60+
builder.add(") {\n")
61+
body
62+
builder.add("}\n")
63+
64+
template addSingleIfStmtWithCond(builder: var Builder, condBody: typed, body: typed) =
65+
builder.add("if (")
66+
condBody
67+
builder.add(") {\n")
68+
body
69+
builder.add("}\n")
70+
71+
type IfStmt = object
72+
needsElse: bool
73+
74+
template addIfStmt(builder: var Builder, stmt: out IfStmt, body: typed) =
75+
stmt = IfStmt(needsElse: false)
76+
body
77+
builder.add("\n")
78+
79+
template addElifBranch(builder: var Builder, stmt: var IfStmt, cond: Snippet, body: typed) =
80+
if stmt.needsElse:
81+
builder.add(" else ")
82+
else:
83+
stmt.needsElse = true
84+
builder.add("if (")
85+
builder.add(cond)
86+
builder.add(") {\n")
87+
body
88+
builder.add("}")
89+
90+
template addElseBranch(builder: var Builder, stmt: var IfStmt, body: typed) =
91+
assert stmt.needsElse
92+
builder.add(" else {\n")
93+
body
94+
builder.add("}")

0 commit comments

Comments
 (0)