Skip to content

Commit

Permalink
nifc gen part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Nov 20, 2024
1 parent e28d2f4 commit f9a8891
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 195 deletions.
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

0 comments on commit f9a8891

Please sign in to comment.