Skip to content

Commit bd36acc

Browse files
committed
to_string
1 parent 94df04b commit bd36acc

File tree

4 files changed

+192
-27
lines changed

4 files changed

+192
-27
lines changed

src/compiler.pr

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6687,7 +6687,7 @@ def do_create_type(tpe: *Type, svalue: *scope::Value, module: *toolchain::Module
66876687
type_names[0] = { kind = ValueKind::INT, tpe = builtins::int64_, i = vector::length(typechecking::get_member_functions(tpe)) } !Value
66886688
type_names[1] = { kind = ValueKind::UNDEF, tpe = pointer(builtins::Function_) } !Value
66896689

6690-
value.values = zero_allocate(Value, 14)
6690+
value.values = zero_allocate(Value, 15)
66916691
value.values[1] = { kind = ValueKind::STRUCT, tpe = builtins::string_, values = name_values } !Value
66926692
value.values[2] = { kind = ValueKind::INT, tpe = builtins::bool_, i = tpe.unsig !int64 } !Value
66936693
value.values[3] = { kind = ValueKind::UNDEF, tpe = builtins::size_t_ } !Value
@@ -6701,29 +6701,30 @@ def do_create_type(tpe: *Type, svalue: *scope::Value, module: *toolchain::Module
67016701
value.values[11] = { kind = ValueKind::STRUCT, tpe = builtins::string_, values = module_values } !Value
67026702
value.values[12] = { kind = ValueKind::UNDEF, tpe = array(builtins::Function_) } !Value
67036703
value.values[13] = { kind = ValueKind::STRUCT, tpe = array(builtins::Function_), values = type_names } !Value
6704+
value.values[14] = { kind = ValueKind::UNDEF, tpe = pointer(builtins::Type_) } !Value
67046705

67056706
let index = allocate(Value, 3)
67066707
index[0] = make_int_value(0)
67076708
index[1] = make_int_value(1)
67086709
index[2] = make_int_value(1)
67096710

67106711
let gep_ret = make_local_value(pointer(pointer(builtins::char_)), null, state)
6711-
let gep = make_insn(InsnKind::GETELEMENTPTR)
6712-
gep.value.gep = {
6712+
let gep1 = make_insn(InsnKind::GETELEMENTPTR)
6713+
gep1.value.gep = {
67136714
ret = gep_ret,
67146715
tpe = builtins::Type_,
67156716
value = global,
67166717
index = index
67176718
} !InsnGetElementPtr
6718-
push_insn(gep, state)
6719+
push_insn(gep1, state)
67196720

67206721
let name = charp(name_str, state)
6721-
let store = make_insn(InsnKind::STORE)
6722-
store.value.store = {
6722+
let store1 = make_insn(InsnKind::STORE)
6723+
store1.value.store = {
67236724
loc = gep_ret,
67246725
value = name
67256726
} !InsnStore
6726-
push_insn(store, state)
6727+
push_insn(store1, state)
67276728

67286729
let index2 = allocate(Value, 3)
67296730
index2[0] = make_int_value(0)
@@ -6748,6 +6749,12 @@ def do_create_type(tpe: *Type, svalue: *scope::Value, module: *toolchain::Module
67486749
} !InsnStore
67496750
push_insn(store2, state)
67506751

6752+
if tpe.kind != typechecking::TypeKind::REFERENCE {
6753+
let value = @create_type(reference(tpe), module)
6754+
let gep_ret = state.gep(pointer(pointer(builtins::Type_)), builtins::Type_, global, [make_int_value(0), make_int_value(14)])
6755+
state.store(gep_ret, value)
6756+
}
6757+
67516758
switch tpe.kind !int {
67526759
case TypeKind::STRUCT, TypeKind::UNION:
67536760
value.values[0] = { kind = ValueKind::INT, tpe = builtins::int_, i = 3 if tpe.kind == TypeKind::STRUCT else 4 } !Value

src/runtime.pr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type Type = struct {
4141
module: string
4242
structural_members: [Function]
4343
type_members: [Function]
44+
ref_wrap: *Type
4445
}
4546

4647
export type EnumValue = struct {
@@ -175,4 +176,11 @@ export def equals(a: *Type, b: *Type) -> bool {
175176
}
176177

177178
return a.name == b.name
179+
}
180+
181+
export def reference(tpe: *Type) -> *Type {
182+
if tpe.kind != TypeKind::REFERENCE {
183+
return tpe.ref_wrap
184+
}
185+
return null
178186
}

std/std.pr

Lines changed: 169 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,150 @@ export const SEEK_SET = 0
2727
export const SEEK_CUR = 1
2828
export const SEEK_END = 2
2929

30+
// String functions
3031
export def make_string(ptr: *char) -> string {
3132
var s: string
3233
s.value = ptr
3334
s.size = strlen(ptr) + 1
3435
return s
3536
}
3637

38+
export type ToString = interface {
39+
def to_string -> &string
40+
}
41+
42+
// TODO remove special casing this
43+
export def == (a: string, b: string) -> bool {
44+
return strncmp(a.value, b.value, max(a.size - 1, b.size - 1) !size_t) == 0
45+
}
46+
47+
export def == (a: string, b: &string) -> bool {
48+
if b { return a == @b }
49+
return false
50+
}
51+
52+
export def == (a: &string, b: string) -> bool {
53+
if a { return @a == b }
54+
return false
55+
}
56+
57+
export def == (a: &string, b: &string) -> bool {
58+
if not a and not b { return true }
59+
if not a or not b { return false }
60+
return @a == @b
61+
}
62+
63+
export def + (a: &string, b: &string) -> &string {
64+
let ret = allocate(char, a.size + b.size - 1)
65+
defer delete(ret)
66+
memcopy(a.value, ret.value, a.size - 1)
67+
memcopy(b.value, ret.value ++ (a.size - 1), b.size - 1)
68+
ret[ret.size - 1] = 0
69+
return ret !&string
70+
}
71+
72+
export def + (a: &string, b: &ToString) -> &string {
73+
return a + b.to_string()
74+
}
75+
76+
export def += (a: &string, b: &ToString) -> &string {
77+
@a = @(a + b.to_string())
78+
return a
79+
}
80+
81+
export def + (a: &ToString, b: &string) -> &string {
82+
return a.to_string() + b
83+
}
84+
85+
// These are defined for better performance
86+
export def + (a: char, b: &string) -> &string {
87+
let ret = allocate(char, b.size + 1)
88+
defer delete(ret)
89+
memcopy(b.value, ret.value ++ 1, b.size - 1)
90+
ret[0] = a
91+
ret[ret.size - 1] = 0
92+
return ret !&string
93+
}
94+
95+
export def + (a: &string, b: char) -> &string {
96+
let ret = allocate(char, a.size + 1)
97+
defer delete(ret)
98+
memcopy(a.value, ret.value, a.size - 1)
99+
ret[ret.size - 2] = b
100+
ret[ret.size - 1] = 0
101+
return ret !&string
102+
}
103+
104+
export def += (a: &string, b: char) -> &string {
105+
@a = @(a + b)
106+
return a
107+
}
108+
109+
def to_string(sign: int, n: uint64) -> &string {
110+
let digits = "0123456789"
111+
112+
var str: &string = ""
113+
if n == 0 {
114+
str += '0'
115+
return str
116+
}
117+
118+
while n {
119+
str = digits[n % 10] + str
120+
n /= 10
121+
}
122+
123+
if sign < 0 {
124+
str = '-' + str
125+
}
126+
127+
return str
128+
}
129+
130+
export def to_string(a: &int64) -> &string {
131+
let n = -@a if @a < 0 else @a
132+
return to_string(1 if @a >= 0 else -1, n)
133+
}
134+
135+
export def to_string(a: &int32) -> &string {
136+
let n = -@a if @a < 0 else @a
137+
return to_string(1 if @a >= 0 else -1, n)
138+
}
139+
140+
export def to_string(a: &int16) -> &string {
141+
let n = -@a if @a < 0 else @a
142+
return to_string(1 if @a >= 0 else -1, n)
143+
}
144+
145+
export def to_string(a: &int8) -> &string {
146+
let n = -@a if @a < 0 else @a
147+
return to_string(1 if @a >= 0 else -1, n)
148+
}
149+
150+
export def to_string(a: &uint64) -> &string {
151+
return to_string(0, @a)
152+
}
153+
154+
export def to_string(a: &uint32) -> &string {
155+
return to_string(0, @a)
156+
}
157+
158+
export def to_string(a: &uint16) -> &string {
159+
return to_string(0, @a)
160+
}
161+
162+
export def to_string(a: &uint8) -> &string {
163+
return to_string(0, @a)
164+
}
165+
166+
export def to_string(a: &bool) -> &string {
167+
return "true" if @a else "false"
168+
}
169+
170+
export def to_string(a: &char) -> &string {
171+
return [@a]
172+
}
173+
37174
export def print(args: &...) -> int {
38175
return fprint(stdout(), args)
39176
}
@@ -42,7 +179,17 @@ export def error(args: &...) -> int {
42179
return fprint(stderr(), args)
43180
}
44181

45-
def print_val(file: File, tpe: *runtime::Type, value: *) -> int {
182+
def make_ref(tpe: *runtime::Type, value: *) -> runtime::Ref {
183+
var ref: runtime::Ref
184+
ref.tpe = runtime::reference(tpe)
185+
ref.value = value
186+
return ref
187+
}
188+
189+
def print_val(file: File, ref: runtime::Ref) -> int {
190+
let reftpe = runtime::ref_type(ref)
191+
let tpe = reftpe.tpe
192+
let value = ref.value
46193
if not tpe or not value {
47194
return cstd::fprintf(file, "%p".value, value)
48195
} else if tpe == string {
@@ -85,7 +232,7 @@ def print_val(file: File, tpe: *runtime::Type, value: *) -> int {
85232
return cstd::fprintf(file, "%p".value, @(value !**))
86233
} else if tpe.kind == runtime::TypeKind::REFERENCE {
87234
let v = value !*runtime::Ref
88-
return print_val(file, tpe.tpe, v.value)
235+
return print_val(file, make_ref(tpe.tpe, v.value))
89236
} else if tpe.kind == runtime::TypeKind::ARRAY {
90237
let arr = @(value !*[*])
91238
let size = arr.size
@@ -94,7 +241,7 @@ def print_val(file: File, tpe: *runtime::Type, value: *) -> int {
94241

95242
sum += cstd::fprintf(file, "[".value)
96243
for var i in 0..size {
97-
sum += print_val(file, tpe.tpe, elements ++ i * tpe.tpe.size)
244+
sum += print_val(file, make_ref(tpe.tpe, elements ++ i * tpe.tpe.size))
98245
if i < size - 1 {
99246
sum += cstd::fprintf(file, ", ".value)
100247
}
@@ -107,27 +254,13 @@ def print_val(file: File, tpe: *runtime::Type, value: *) -> int {
107254

108255
sum += cstd::fprintf(file, "[".value)
109256
for var i in 0..size {
110-
sum += print_val(file, tpe.tpe, value ++ i * tpe.tpe.size)
257+
sum += print_val(file, make_ref(tpe.tpe, value ++ i * tpe.tpe.size))
111258
if i < size - 1 {
112259
sum += cstd::fprintf(file, ", ".value)
113260
}
114261
}
115262
sum += cstd::fprintf(file, "]".value)
116263
return sum
117-
} else if tpe.kind == runtime::TypeKind::STRUCT or tpe.kind == runtime::TypeKind::UNION {
118-
let fields = tpe.fields
119-
var sum = 0
120-
sum += cstd::fprintf(file, "{".value)
121-
for var i in 0..fields.size {
122-
let field = fields[i]
123-
sum += cstd::fprintf(file, "%s = ".value, field.name.value)
124-
sum += print_val(file, field.tpe, value ++ field.offset)
125-
if i < fields.size - 1 {
126-
sum += cstd::fprintf(file, ", ".value)
127-
}
128-
}
129-
sum += cstd::fprintf(file, "} !%s".value, tpe.name.value)
130-
return sum
131264
} else if tpe.kind == runtime::TypeKind::ENUM {
132265
var v: int64 = 0
133266
for var i in 0..tpe.tpe.size {
@@ -142,14 +275,31 @@ def print_val(file: File, tpe: *runtime::Type, value: *) -> int {
142275
}
143276
}
144277
return cstd::fprintf(file, "%s".value, str.value)
278+
} else if runtime::implements(reftpe, ToString) {
279+
let str = (ref !&ToString).to_string()
280+
return cstd::fprintf(file, "%s".value, (@str).value)
281+
} else if tpe.kind == runtime::TypeKind::STRUCT or tpe.kind == runtime::TypeKind::UNION {
282+
let fields = tpe.fields
283+
var sum = 0
284+
sum += cstd::fprintf(file, "{".value)
285+
for var i in 0..fields.size {
286+
let field = fields[i]
287+
sum += cstd::fprintf(file, "%s = ".value, field.name.value)
288+
sum += print_val(file, make_ref(field.tpe, value ++ field.offset))
289+
if i < fields.size - 1 {
290+
sum += cstd::fprintf(file, ", ".value)
291+
}
292+
}
293+
sum += cstd::fprintf(file, "} !%s".value, tpe.name.value)
294+
return sum
145295
}
146296
}
147297

148298
export def fprint(file: File, args: &...) -> int {
149299
var sum = 0
150300
for var i in 0..args.size {
151301
let arg = args[i]
152-
sum += print_val(file, runtime::ref_type(arg).tpe, arg !*)
302+
sum += print_val(file, make_ref(ref_type(arg).tpe, arg !*))
153303
}
154304
return sum
155305
}

version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION=0.1.22
1+
VERSION=0.2.0

0 commit comments

Comments
 (0)