@@ -4,6 +4,9 @@ pub unsafe fn read_u64(ptr: *const u8) -> u64 {
4
4
pub unsafe fn read_u32 ( ptr : * const u8 ) -> u32 {
5
5
ptr. cast :: < u32 > ( ) . read_unaligned ( )
6
6
}
7
+ pub unsafe fn read_u16 ( ptr : * const u8 ) -> u16 {
8
+ ptr. cast :: < u16 > ( ) . read_unaligned ( )
9
+ }
7
10
8
11
pub const MAGIC : u32 = 0xABADBABA ;
9
12
@@ -15,6 +18,7 @@ pub type Result<T> = std::result::Result<T, VMError>;
15
18
pub enum Value {
16
19
Null ,
17
20
LiteralString ( * const u8 ) , // Pointer to length-prepended string in code segment
21
+ String ( Vec < u8 > ) ,
18
22
Bool ( bool ) ,
19
23
}
20
24
@@ -33,25 +37,79 @@ impl Value {
33
37
b"false"
34
38
}
35
39
}
40
+ Value :: String ( s) => & s,
36
41
}
37
42
}
38
43
39
44
pub fn to_bool ( & self ) -> bool {
40
45
match self {
41
46
Value :: Null => false ,
42
47
lit_str @ Value :: LiteralString ( _) => lit_str. to_bytes ( ) . len ( ) == 0 ,
48
+ Value :: String ( s) => s. len ( ) == 0 ,
43
49
Value :: Bool ( b) => * b,
44
50
}
45
51
}
52
+
53
+ pub fn add ( self , other : Value ) -> Value {
54
+ match self {
55
+ Value :: Null => match other {
56
+ Value :: Null => Value :: Null ,
57
+ v @ Value :: LiteralString ( _) => v. clone ( ) ,
58
+ Value :: Bool ( _) => todo ! ( ) ,
59
+ Value :: String ( _) => todo ! ( ) ,
60
+ } ,
61
+ self_lit_str @ Value :: LiteralString ( self_ptr) => match other {
62
+ Value :: LiteralString ( other_ptr) => unsafe {
63
+ let self_len = read_u32 ( self_ptr) as usize ;
64
+ let other_len = read_u32 ( other_ptr) as usize ;
65
+ let mut out = Vec :: with_capacity ( self_len + other_len) ;
66
+ let dst = out. as_mut_ptr ( ) ;
67
+
68
+ std:: ptr:: copy_nonoverlapping ( self_ptr. add ( 4 ) , dst, self_len) ;
69
+ std:: ptr:: copy_nonoverlapping ( other_ptr. add ( 4 ) , dst. add ( self_len) , other_len) ;
70
+
71
+ out. set_len ( self_len + other_len) ;
72
+
73
+ Value :: String ( out)
74
+ } ,
75
+ Value :: Null => self_lit_str. clone ( ) ,
76
+ Value :: Bool ( _) => todo ! ( ) , // TODO: might need to coerce the bool to a string here
77
+ Value :: String ( other_str) => {
78
+ let mut out = Vec :: new ( ) ;
79
+ out. extend_from_slice ( self_lit_str. to_bytes ( ) ) ;
80
+ out. extend_from_slice ( & other_str) ;
81
+ Value :: String ( out)
82
+ }
83
+ } ,
84
+ Value :: Bool ( self_b) => match other {
85
+ Value :: Bool ( other_b) => todo ! ( ) ,
86
+ Value :: Null => todo ! ( ) ,
87
+ Value :: LiteralString ( _) => todo ! ( ) ,
88
+ Value :: String ( _) => todo ! ( ) ,
89
+ } ,
90
+ Value :: String ( self_str) => match other {
91
+ Value :: Bool ( other_b) => todo ! ( ) ,
92
+ Value :: Null => todo ! ( ) ,
93
+ other_lit_str @ Value :: LiteralString ( _) => {
94
+ let mut out = Vec :: new ( ) ;
95
+ out. extend_from_slice ( & self_str) ;
96
+ out. extend_from_slice ( other_lit_str. to_bytes ( ) ) ;
97
+ Value :: String ( out)
98
+ }
99
+ Value :: String ( _) => todo ! ( ) ,
100
+ } ,
101
+ }
102
+ }
46
103
}
47
104
48
105
impl PartialEq for Value {
49
106
fn eq ( & self , other : & Value ) -> bool {
50
107
match self {
51
108
Value :: Null => match other {
52
109
Value :: Null => true ,
53
- Value :: LiteralString ( _) => false ,
54
- Value :: Bool ( _) => false , // TODO: not sure if null == false
110
+ Value :: LiteralString ( _) => false , // TODO: empty string might equal null?
111
+ Value :: String ( _) => false , // TODO: empty string might equal null?
112
+ Value :: Bool ( _) => false , // TODO: not sure if null == false
55
113
} ,
56
114
Value :: LiteralString ( self_ptr) => match other {
57
115
Value :: LiteralString ( other_ptr) => {
@@ -63,13 +121,21 @@ impl PartialEq for Value {
63
121
self . to_bytes ( ) == other. to_bytes ( )
64
122
}
65
123
}
124
+ Value :: String ( other_str) => self . to_bytes ( ) == * other_str,
66
125
Value :: Null => false ,
67
126
Value :: Bool ( _) => false , // TODO: might need to coerce the bool to a string here
68
127
} ,
69
128
Value :: Bool ( self_b) => match other {
70
129
Value :: Bool ( other_b) => self_b == other_b,
71
130
Value :: Null => false ,
72
131
Value :: LiteralString ( _) => false , // TODO: ditto above re: coercion
132
+ Value :: String ( _) => false , // TODO: ditto above re: coercion
133
+ } ,
134
+ Value :: String ( self_str) => match other {
135
+ Value :: Bool ( other_b) => todo ! ( ) ,
136
+ Value :: Null => false ,
137
+ Value :: LiteralString ( _) => todo ! ( ) ,
138
+ Value :: String ( other_str) => self_str == other_str,
73
139
} ,
74
140
}
75
141
}
0 commit comments