Skip to content

Commit

Permalink
Slim down runtime and rewrite std::print
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Oct 12, 2024
1 parent 376d731 commit 96d2b1f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 261 deletions.
202 changes: 0 additions & 202 deletions src/runtime.pr
Original file line number Diff line number Diff line change
Expand Up @@ -27,68 +27,13 @@ export def next(generator: &Generator(type T)) -> optional::Optional(T) {
return generator.implementation(generator)
}

export type TypeKind = enum {
BOOL
WORD
FLOAT
STRUCT
UNION
ARRAY
STATIC_ARRAY
POINTER
REFERENCE
FUNCTION
ENUM
CHAR
STRUCTURAL
OPAQUE
WEAK_REF
TYPE
VARIANT
TUPLE
}

export type Function = struct {
name: string
exported: bool
module: string
parameter_t: [*Type]
return_t: [*Type]
}

// TODO Potentially preserve type names
export type Type = struct {
kind: TypeKind
name: string
unsig: bool
length: size_t
tpe: *Type
size: size_t
align: size_t
fields: [Field]
parameters: [*Type]
returns: [*Type]
enum_values: [EnumValue]
module: string
structural_members: [Function]
type_members: [Function]
id: int64

destructor: def * -> []
constuctor: def [*, *] -> []
}

export type EnumValue = struct {
name: string
value: int64
}

export type Field = struct {
name: string
offset: size_t
tpe: *Type
}

export type Refcount = struct {
strong_cnt: int64
weak_cnt: int64
Expand All @@ -98,151 +43,4 @@ export type Ref = struct {
ref_count: *Refcount
value: *
tpe: *Type
}

// TODO We can probably live without the allocation in here if we directly compare the values
def cut_name(s: string) -> string {
var end = 0
while s(end) != '(' and end < s.size - 1 {
end += 1
}
if s(end) == '(' {
end -= 2
}

var start = end - 1
while s(start) != ':' and start > 0 {
start -= 1
}
if s(start) == ':' {
start += 1
}

let size = end - start
var ret: string
ret.value = cstd::malloc((size + 1) * (size_of char)) !*char
cstd::memcpy(ret.value, s.value ++ start, size)
@(ret.value ++ size) = '\0'
ret.size = size + 1

return ret
}

// TODO Need to do structural type implements structural type
export def implements(A: *Type, B: *Type) -> bool {
// TODO We want to log something here
if B.kind != TypeKind::STRUCTURAL { cstd::abort() }

for var i in 0..B.structural_members.size {
let member = B.structural_members(i)

var found = false
for var j in 0..A.type_members.size {
let type_member = A.type_members(j)
// Exported
if A.module != type_member.module and not type_member.exported { continue }

// Name
let name = cut_name(type_member.name)
if name != member.name {
cstd::free(name.value)
continue
}
cstd::free(name.value)

// Parameter types
if type_member.parameter_t.size != member.parameter_t.size + 1 { continue }

// TODO work around missing goto
var mismatch = false
for var i in 0..member.parameter_t.size {
let left = member.parameter_t(i)
let right = type_member.parameter_t(i + 1)
if not equals(left, right) {
mismatch = true
break
}
}
if mismatch { continue }

// Return types
if type_member.return_t.size != member.return_t.size { continue }
for var i in 0..member.return_t.size {
let left = member.return_t(i)
let right = type_member.return_t(i)
if not equals(left, right) {
mismatch = true
break
}
}
if mismatch { continue }

found = true
break
}
if not found { return false }
}
return true
}

export def ref_type(a: Ref) -> *Type {
return a.tpe
}

export def equals(a: *Type, b: *Type) -> bool {
if a !* == b !* { return true }
if not a or not b { return false }
if a.kind != b.kind { return false }
if a.kind == TypeKind::BOOL or a.kind == TypeKind::CHAR { return true }
if a.kind == TypeKind::WORD {
return a.size == b.size and a.unsig == b.unsig
}
if a.kind == TypeKind::FLOAT {
return a.size == b.size
}
if a.kind == TypeKind::STATIC_ARRAY {
return a.length == b.length and equals(a.tpe, b.tpe)
}
if a.kind == TypeKind::ARRAY or a.kind == TypeKind::POINTER or a.kind == TypeKind::REFERENCE {
return equals(a.tpe, b.tpe)
}
if a.kind == TypeKind::FUNCTION {
if a.parameters.size != b.parameters.size { return false }
if a.returns.size != b.returns.size { return false }
for var i in 0..a.parameters.size {
if not equals(a.parameters(i).tpe, b.parameters(i).tpe) { return false }
}
for var i in 0..a.returns.size {
if not equals(a.returns(i), b.returns(i)) { return false }
}
}
if a.kind == TypeKind::VARIANT {
if a.parameters.size != b.parameters.size { return false }
for var va in a.parameters {
var found = false
for var vb in b.parameters {
if equals(va, vb) {
found = true
break
}
}
if not found { return false }
}
return true
}

return a.id == b.id
}

// Caller must clean up
export def reference(tpe: *Type) -> *Type {
if not tpe { return null }
let ret = cstd::malloc(size_of Type) !*Type
@ret = [
kind = TypeKind::REFERENCE,
size = size_of &,
align = align_of &,
tpe = tpe
] !Type
return ret
}
Loading

0 comments on commit 96d2b1f

Please sign in to comment.