Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nifc generation #24459

Draft
wants to merge 14 commits into
base: devel
Choose a base branch
from
266 changes: 193 additions & 73 deletions compiler/cbuilderbase.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import ropes, int128
import ropes, int128, std/formatfloat

const buildNifc* = defined(nimCompileToNifc)

type
Snippet* = string
Expand Down Expand Up @@ -43,119 +45,237 @@ proc addLineEndDedent*(builder: var Builder, s: string) =
builder.addNewline()

proc addLineComment*(builder: var Builder, comment: string) =
# probably no-op on nifc
builder.add("// ")
builder.add(comment)
builder.addNewline()
when not buildNifc:
builder.add("// ")
builder.add(comment)
builder.addNewline()

proc addIntValue*(builder: var Builder, val: int) =
when buildNifc:
if val >= 0:
builder.buf.add('+')
builder.buf.addInt(val)

proc addIntValue*(builder: var Builder, val: int64) =
when buildNifc:
if val >= 0:
builder.buf.add('+')
builder.buf.addInt(val)

proc addIntValue*(builder: var Builder, val: uint64) =
when buildNifc:
builder.buf.add('+')
builder.buf.addInt(val)

proc addIntValue*(builder: var Builder, val: Int128) =
when buildNifc:
if val >= 0:
builder.buf.add('+')
builder.buf.addInt128(val)

template cIntValue*(val: int): Snippet = $val
template cIntValue*(val: int64): Snippet = $val
template cIntValue*(val: uint64): Snippet = $val
template cIntValue*(val: Int128): Snippet = $val

template cUintValue*(val: uint): Snippet = $val & "U"

import std/formatfloat

proc addFloatValue*(builder: var Builder, val: float) =
builder.buf.addFloat(val)

template cFloatValue*(val: float): Snippet = $val
when not buildNifc:
template cIntValue*(val: int): Snippet = $val
template cIntValue*(val: int64): Snippet = $val
template cIntValue*(val: uint64): Snippet = $val
template cIntValue*(val: Int128): Snippet = $val

template cUintValue*(val: uint): Snippet = $val & "U"

proc addFloatValue*(builder: var Builder, val: float) =
builder.buf.addFloat(val)

template cFloatValue*(val: float): Snippet = $val
else:
proc cIntValue*(val: int): Snippet =
result = if val >= 0: "+" else: ""
result.addInt(val)
proc cIntValue*(val: int64): Snippet =
result = if val >= 0: "+" else: ""
result.addInt(val)
proc cIntValue*(val: uint64): Snippet =
result = "+"
result.addInt(val)
proc cIntValue*(val: Int128): Snippet =
result = if val >= 0: "+" else: ""
result.addInt128(val)
proc cUintValue*(val: uint): Snippet =
result = "+"
result.addInt(val)
result.add('u')

import std/math

proc addFloatValue*(builder: var Builder, val: float) =
let kind = classify(val)
case kind
of fcNan:
builder.buf.add("(nan)")
of fcInf:
builder.buf.add("(inf)")
of fcNegInf:
builder.buf.add("(neginf)")
else:
if val >= 0:
builder.buf.add("+")
builder.buf.addFloat(val)

proc cFloatValue*(val: float): Snippet =
let kind = classify(val)
case kind
of fcNan:
result = "(nan)"
of fcInf:
result = "(inf)"
of fcNegInf:
result = "(neginf)"
else:
result = if val >= 0: "+" else: "-"
result.addFloat(val)

proc addInt64Literal*(result: var Builder; i: BiggestInt) =
if i > low(int64):
result.add "IL64($1)" % [rope(i)]
when buildNifc:
result.add("(suf ")
result.addIntValue(i)
result.add(" \"i64\")")
else:
result.add "(IL64(-9223372036854775807) - IL64(1))"
if i > low(int64):
result.add "IL64($1)" % [rope(i)]
else:
result.add "(IL64(-9223372036854775807) - IL64(1))"

proc addUint64Literal*(result: var Builder; i: uint64) =
result.add rope($i & "ULL")
when buildNifc:
result.add("(suf ")
result.addIntValue(i)
result.add('u')
result.add(" \"u64\")")
else:
result.add rope($i & "ULL")

proc addIntLiteral*(result: var Builder; i: BiggestInt) =
if i > low(int32) and i <= high(int32):
when buildNifc:
# nifc handles this
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))"
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 addIntLiteral*(result: var Builder; i: Int128) =
addIntLiteral(result, toInt64(i))

proc cInt64Literal*(i: BiggestInt): Snippet =
if i > low(int64):
result = "IL64($1)" % [rope(i)]
when buildNifc:
result = "(suf " & cIntValue(i) & " \"i64\")"
else:
result = "(IL64(-9223372036854775807) - IL64(1))"
if i > low(int64):
result = "IL64($1)" % [rope(i)]
else:
result = "(IL64(-9223372036854775807) - IL64(1))"

proc cUint64Literal*(i: uint64): Snippet =
result = $i & "ULL"
when buildNifc:
result = "(suf " & cUintValue(i) & " \"u64\")"
else:
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)]
when buildNifc:
result = cIntValue(i)
else:
result = "(IL64(-9223372036854775807) - IL64(1))"
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))

const
NimInt* = "NI"
NimInt8* = "NI8"
NimInt16* = "NI16"
NimInt32* = "NI32"
NimInt64* = "NI64"
CInt* = "int"
NimUint* = "NU"
NimUint8* = "NU8"
NimUint16* = "NU16"
NimUint32* = "NU32"
NimUint64* = "NU64"
NimFloat* = "NF"
NimFloat32* = "NF32"
NimFloat64* = "NF64"
NimFloat128* = "NF128" # not actually defined
NimNan* = "NAN"
NimInf* = "INF"
NimBool* = "NIM_BOOL"
NimTrue* = "NIM_TRUE"
NimFalse* = "NIM_FALSE"
NimChar* = "NIM_CHAR"
CChar* = "char"
NimCstring* = "NCSTRING"
NimNil* = "NIM_NIL"
CNil* = "NULL"
NimStrlitFlag* = "NIM_STRLIT_FLAG"
CVoid* = "void"
CPointer* = "void*"
CConstPointer* = "NIM_CONST void*"
when buildNifc:
const
NimInt* = "(i -1)"
NimInt8* = "(i +8)"
NimInt16* = "(i +16)"
NimInt32* = "(i +32)"
NimInt64* = "(i +64)"
CInt* = "(i +32)" # int.c
NimUint* = "(u -1)"
NimUint8* = "(u +8)"
NimUint16* = "(u +16)"
NimUint32* = "(u +32)"
NimUint64* = "(u +64)"
NimFloat* = "(f +64)"
NimFloat32* = "(f +32)"
NimFloat64* = "(f +64)"
NimFloat128* = "(f +128)"
NimNan* = "(nan)"
NimInf* = "(inf)"
NimBool* = "(bool)"
NimTrue* = "(true)"
NimFalse* = "(false)"
NimChar* = "(c +8)"
CChar* = "(c +8)" # char.c
NimCstring* = "(ptr (c +8))"
NimNil* = "(nil)"
CNil* = "(nil)" # NULL.c
NimStrlitFlag* = "NIM_STRLIT_FLAG" # XXX
CVoid* = "(void)"
CPointer* = "(ptr (void))"
CConstPointer* = "(ptr (void))" # (void (ro)) illegal
else:
const
NimInt* = "NI"
NimInt8* = "NI8"
NimInt16* = "NI16"
NimInt32* = "NI32"
NimInt64* = "NI64"
CInt* = "int"
NimUint* = "NU"
NimUint8* = "NU8"
NimUint16* = "NU16"
NimUint32* = "NU32"
NimUint64* = "NU64"
NimFloat* = "NF"
NimFloat32* = "NF32"
NimFloat64* = "NF64"
NimFloat128* = "NF128" # not actually defined
NimNan* = "NAN"
NimInf* = "INF"
NimBool* = "NIM_BOOL"
NimTrue* = "NIM_TRUE"
NimFalse* = "NIM_FALSE"
NimChar* = "NIM_CHAR"
CChar* = "char"
NimCstring* = "NCSTRING"
NimNil* = "NIM_NIL"
CNil* = "NULL"
NimStrlitFlag* = "NIM_STRLIT_FLAG"
CVoid* = "void"
CPointer* = "void*"
CConstPointer* = "NIM_CONST void*"

proc cIntType*(bits: BiggestInt): Snippet =
"NI" & $bits
when buildNifc:
"(i +" & $bits & ")"
else:
"NI" & $bits

proc cUintType*(bits: BiggestInt): Snippet =
"NU" & $bits
when buildNifc:
"(u +" & $bits & ")"
else:
"NU" & $bits

type
IfBuilderState* = enum
Expand Down
Loading