1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: fix struct order bug

This commit is contained in:
Alexander Medvednikov
2019-08-29 01:52:32 +03:00
parent c6b79dfd24
commit 2fe20cd092
4 changed files with 199 additions and 156 deletions

View File

@ -4,19 +4,19 @@
module builtin
import strings
import strings
struct map {
element_size int
root *Node
pub:
size int
root *mapnode
pub:
size int
}
struct Node {
left *Node
right *Node
is_empty bool
struct mapnode {
left *mapnode
right *mapnode
is_empty bool
key string
val voidptr
}
@ -24,108 +24,108 @@ struct Node {
fn new_map(cap, elm_size int) map {
res := map {
element_size: elm_size
root: 0
root: 0
}
return res
}
// `m := { 'one': 1, 'two': 2 }`
// `m := { 'one': 1, 'two': 2 }`
fn new_map_init(cap, elm_size int, keys *string, vals voidptr) map {
mut res := map {
element_size: elm_size
root: 0
root: 0
}
for i in 0 .. cap {
res._set(keys[i], vals + i * elm_size)
}
res._set(keys[i], vals + i * elm_size)
}
return res
}
}
fn new_node(key string, val voidptr, element_size int) *Node {
new_e := &Node {
fn new_node(key string, val voidptr, element_size int) *mapnode {
new_e := &mapnode {
key: key
val: malloc(element_size)
left: 0
right: 0
right: 0
}
C.memcpy(new_e.val, val, element_size)
return new_e
}
fn (m mut map) insert(n mut Node, key string, val voidptr) {
fn (m mut map) insert(n mut mapnode, key string, val voidptr) {
if n.key == key {
C.memcpy(n.val, val, m.element_size)
return
}
return
}
if n.key > key {
if isnil(n.left) {
n.left = new_node(key, val, m.element_size)
m.size++
} else {
m.insert(mut n.left, key, val)
}
return
}
n.left = new_node(key, val, m.element_size)
m.size++
} else {
m.insert(mut n.left, key, val)
}
return
}
if isnil(n.right) {
n.right = new_node(key, val, m.element_size)
m.size++
} else {
m.insert(mut n.right, key, val)
}
}
n.right = new_node(key, val, m.element_size)
m.size++
} else {
m.insert(mut n.right, key, val)
}
}
fn (n & Node) find(key string, out voidptr, element_size int) bool{
fn (n & mapnode) find(key string, out voidptr, element_size int) bool{
if n.key == key {
C.memcpy(out, n.val, element_size)
return true
}
return true
}
else if n.key > key {
if isnil(n.left) {
return false
} else {
return n.left.find(key, out, element_size)
}
}
return false
} else {
return n.left.find(key, out, element_size)
}
}
else {
if isnil(n.right) {
return false
} else {
return n.right.find(key, out, element_size)
}
return false
} else {
return n.right.find(key, out, element_size)
}
}
}
}
// same as `find`, but doesn't return a value. Used by `exists`
fn (n & Node) find2(key string, element_size int) bool{
// same as `find`, but doesn't return a value. Used by `exists`
fn (n & mapnode) find2(key string, element_size int) bool{
if n.key == key {
return true
}
return true
}
else if n.key > key {
if isnil(n.left) {
return false
} else {
return n.left.find2(key, element_size)
}
}
return false
} else {
return n.left.find2(key, element_size)
}
}
else {
if isnil(n.right) {
return false
} else {
return n.right.find2(key, element_size)
}
return false
} else {
return n.right.find2(key, element_size)
}
}
}
}
fn (m mut map) _set(key string, val voidptr) {
if isnil(m.root) {
m.root = new_node(key, val, m.element_size)
m.size++
return
}
m.insert(mut m.root, key, val)
m.root = new_node(key, val, m.element_size)
m.size++
return
}
m.insert(mut m.root, key, val)
}
/*
/*
fn (m map) bs(query string, start, end int, out voidptr) {
// println('bs "$query" $start -> $end')
mid := start + ((end - start) / 2)
@ -150,23 +150,23 @@ fn (m map) bs(query string, start, end int, out voidptr) {
}
m.bs(query, mid, end, out)
}
*/
*/
fn preorder_keys(node &Node, keys mut []string, key_i int) int {
fn preorder_keys(node &mapnode, keys mut []string, key_i int) int {
mut i := key_i
if !node.is_empty {
mut a := *keys
a[i] = node.key
i++
}
if !isnil(node.left) {
if !isnil(node.left) {
i = preorder_keys(node.left, mut keys, i)
}
if !isnil(node.right) {
}
if !isnil(node.right) {
i = preorder_keys(node.right, mut keys, i)
}
return i
}
}
pub fn (m mut map) keys() []string {
mut keys := [''; m.size]
@ -179,44 +179,44 @@ pub fn (m mut map) keys() []string {
fn (m map) get(key string, out voidptr) bool {
if isnil(m.root) {
return false
}
return m.root.find(key, out, m.element_size)
return false
}
return m.root.find(key, out, m.element_size)
}
pub fn (n mut Node) delete(key string, element_size int) {
pub fn (n mut mapnode) delete(key string, element_size int) {
if n.key == key {
C.memset(n.val, 0, element_size)
n.is_empty = true
return
}
n.is_empty = true
return
}
else if n.key > key {
if isnil(n.left) {
return
} else {
n.left.delete(key, element_size)
}
}
return
} else {
n.left.delete(key, element_size)
}
}
else {
if isnil(n.right) {
return
} else {
n.right.delete(key, element_size)
}
}
}
return
} else {
n.right.delete(key, element_size)
}
}
}
pub fn (m mut map) delete(key string) {
m.root.delete(key, m.element_size)
m.size--
}
pub fn (m mut map) delete(key string) {
m.root.delete(key, m.element_size)
m.size--
}
pub fn (m map) exists(key string) bool {
panic('map.exists(key) was removed from the language. Use `key in map` instead.')
panic('map.exists(key) was removed from the language. Use `key in map` instead.')
}
fn (m map) _exists(key string) bool {
return !isnil(m.root) && m.root.find2(key, m.element_size)
return !isnil(m.root) && m.root.find2(key, m.element_size)
}
pub fn (m map) print() {
@ -246,10 +246,10 @@ pub fn (m map_string) str() string {
return '{}'
}
mut sb := strings.new_builder(50)
sb.writeln('{')
for key, val in m {
sb.writeln(' "$key" => "$val"')
sb.writeln('{')
for key, val in m {
sb.writeln(' "$key" => "$val"')
}
sb.writeln('}')
return sb.str()
sb.writeln('}')
return sb.str()
}