Skip to content

Commit

Permalink
cbuilder: ccgexprs sweep part 1, basic if stmts (#24381)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
metagn authored Oct 31, 2024
1 parent 5e56f0a commit 658c9da
Show file tree
Hide file tree
Showing 6 changed files with 483 additions and 322 deletions.
50 changes: 47 additions & 3 deletions compiler/cbuilderbase.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,50 @@ import std/formatfloat
proc addFloatValue(builder: var Builder, val: float) =
builder.addFloat(val)

proc cFloatValue(val: float): Snippet =
result = ""
result.addFloat(val)
template cFloatValue(val: float): Snippet = $val

proc int64Literal(i: BiggestInt; result: var Builder) =
if i > low(int64):
result.add "IL64($1)" % [rope(i)]
else:
result.add "(IL64(-9223372036854775807) - IL64(1))"

proc uint64Literal(i: uint64; result: var Builder) =
result.add rope($i & "ULL")

proc intLiteral(i: BiggestInt; result: var Builder) =
if i > low(int32) and i <= high(int32):
result.addIntValue(i)
elif i == low(int32):
# Nim has the same bug for the same reasons :-)
result.add "(-2147483647 -1)"
elif i > low(int64):
result.add "IL64($1)" % [rope(i)]
else:
result.add "(IL64(-9223372036854775807) - IL64(1))"

proc intLiteral(i: Int128; result: var Builder) =
intLiteral(toInt64(i), result)

proc cInt64Literal(i: BiggestInt): Snippet =
if i > low(int64):
result = "IL64($1)" % [rope(i)]
else:
result = "(IL64(-9223372036854775807) - IL64(1))"

proc cUint64Literal(i: uint64): Snippet =
result = $i & "ULL"

proc cIntLiteral(i: BiggestInt): Snippet =
if i > low(int32) and i <= high(int32):
result = rope(i)
elif i == low(int32):
# Nim has the same bug for the same reasons :-)
result = "(-2147483647 -1)"
elif i > low(int64):
result = "IL64($1)" % [rope(i)]
else:
result = "(IL64(-9223372036854775807) - IL64(1))"

proc cIntLiteral(i: Int128): Snippet =
result = cIntLiteral(toInt64(i))
34 changes: 28 additions & 6 deletions compiler/cbuilderexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
# XXX add stuff like NI, NIM_NIL as constants

proc constType(t: Snippet): Snippet =
# needs manipulation of `t` in nifc
"NIM_CONST " & t

proc constPtrType(t: Snippet): Snippet =
t & "* NIM_CONST"

proc ptrConstType(t: Snippet): Snippet =
"NIM_CONST " & t & "*"

proc ptrType(t: Snippet): Snippet =
t & "*"

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

proc removeSinglePar(value: Snippet): Snippet =
# removes a single paren layer expected to exist, to silence Wparentheses-equality
assert value[0] == '(' and value[^1] == ')'
value[1..^2]

template addCast(builder: var Builder, typ: Snippet, valueBody: typed) =
## adds a cast to `typ` with value built by `valueBody`
builder.add "(("
Expand Down Expand Up @@ -75,16 +87,26 @@ template addCall(builder: var Builder, call: out CallBuilder, callee: Snippet, b
body
finishCallBuilder(builder, call)

proc addNullaryCall(builder: var Builder, callee: Snippet) =
builder.add(callee)
builder.add("()")

proc addUnaryCall(builder: var Builder, callee: Snippet, arg: Snippet) =
proc addCall(builder: var Builder, callee: Snippet, args: varargs[Snippet]) =
builder.add(callee)
builder.add("(")
builder.add(arg)
if args.len != 0:
builder.add(args[0])
for i in 1 ..< args.len:
builder.add(", ")
builder.add(args[i])
builder.add(")")

proc cCall(callee: Snippet, args: varargs[Snippet]): Snippet =
result = callee
result.add("(")
if args.len != 0:
result.add(args[0])
for i in 1 ..< args.len:
result.add(", ")
result.add(args[i])
result.add(")")

proc addSizeof(builder: var Builder, val: Snippet) =
builder.add("sizeof(")
builder.add(val)
Expand Down
78 changes: 72 additions & 6 deletions compiler/cbuilderstmts.nim
Original file line number Diff line number Diff line change
@@ -1,28 +1,94 @@
template addAssignment(builder: var Builder, lhs: Snippet, valueBody: typed) =
template addAssignmentWithValue(builder: var Builder, lhs: Snippet, valueBody: typed) =
builder.add(lhs)
builder.add(" = ")
valueBody
builder.add(";\n")

template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
template addFieldAssignmentWithValue(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
builder.add(lhs)
builder.add("." & name & " = ")
valueBody
builder.add(";\n")

template addDerefFieldAssignment(builder: var Builder, lhs: Snippet, name: string, valueBody: typed) =
template addAssignment(builder: var Builder, lhs, rhs: Snippet) =
builder.addAssignmentWithValue(lhs):
builder.add(rhs)

template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
builder.addFieldAssignmentWithValue(lhs, name):
builder.add(rhs)

template addMutualFieldAssignment(builder: var Builder, lhs, rhs: Snippet, name: string) =
builder.addFieldAssignmentWithValue(lhs, name):
builder.add(rhs)
builder.add("." & name)

template addAssignment(builder: var Builder, lhs: Snippet, rhs: int | int64 | uint64 | Int128) =
builder.addAssignmentWithValue(lhs):
builder.addIntValue(rhs)

template addFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: int | int64 | uint64 | Int128) =
builder.addFieldAssignmentWithValue(lhs, name):
builder.addIntValue(rhs)

template addDerefFieldAssignment(builder: var Builder, lhs: Snippet, name: string, rhs: Snippet) =
builder.add(lhs)
builder.add("->" & name & " = ")
valueBody
builder.add(rhs)
builder.add(";\n")

template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snippet, valueBody: typed) =
template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snippet, rhs: Snippet) =
builder.add(lhs)
builder.add("[" & index & "] = ")
valueBody
builder.add(rhs)
builder.add(";\n")

template addStmt(builder: var Builder, stmtBody: typed) =
## makes an expression built by `stmtBody` into a statement
stmtBody
builder.add(";\n")

proc addCallStmt(builder: var Builder, callee: Snippet, args: varargs[Snippet]) =
builder.addStmt():
builder.addCall(callee, args)

# XXX blocks need indent tracker in `Builder` object

template addSingleIfStmt(builder: var Builder, cond: Snippet, body: typed) =
builder.add("if (")
builder.add(cond)
builder.add(") {\n")
body
builder.add("}\n")

template addSingleIfStmtWithCond(builder: var Builder, condBody: typed, body: typed) =
builder.add("if (")
condBody
builder.add(") {\n")
body
builder.add("}\n")

type IfStmt = object
needsElse: bool

template addIfStmt(builder: var Builder, stmt: out IfStmt, body: typed) =
stmt = IfStmt(needsElse: false)
body
builder.add("\n")

template addElifBranch(builder: var Builder, stmt: var IfStmt, cond: Snippet, body: typed) =
if stmt.needsElse:
builder.add(" else ")
else:
stmt.needsElse = true
builder.add("if (")
builder.add(cond)
builder.add(") {\n")
body
builder.add("}")

template addElseBranch(builder: var Builder, stmt: var IfStmt, body: typed) =
assert stmt.needsElse
builder.add(" else {\n")
body
builder.add("}")
Loading

0 comments on commit 658c9da

Please sign in to comment.