Skip to content

Commit 4bc30ce

Browse files
committed
Store constants as VM values instead of strings
This is kind of a prefactor to adding number expressions to the language
1 parent 7fe6865 commit 4bc30ce

9 files changed

Lines changed: 42 additions & 35 deletions
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
VERSION 0800
22
----
33
0000 GET BUILTIN 0 == 'id'
4-
0003 CONSTANT 0 == 'test'
4+
0003 CONSTANT 0 == '`test`'
55
0005 CALL (1 args)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
VERSION 0800
22
----
33
0000 GET BUILTIN 15 == 'eq'
4-
0003 CONSTANT 0 == 'foo'
5-
0005 CONSTANT 0 == 'foo'
4+
0003 CONSTANT 0 == '`foo`'
5+
0005 CONSTANT 0 == '`foo`'
66
0007 CALL (2 args)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
VERSION 0800
22
----
33
0000 GET BUILTIN 15 == 'eq'
4-
0003 CONSTANT 0 == 'foo'
5-
0005 CONSTANT 1 == 'bar'
4+
0003 CONSTANT 0 == '`foo`'
5+
0005 CONSTANT 1 == '`bar`'
66
0007 CALL (2 args)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
VERSION 0800
22
----
3-
0000 CONSTANT 0 == 'test string'
3+
0000 CONSTANT 0 == '`test string`'
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
VERSION 0800
22
----
33
0000 GET BUILTIN 14 == 'type'
4-
0003 CONSTANT 0 == ''
4+
0003 CONSTANT 0 == '``'
55
0005 CALL (1 args)

src/compiler.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
},
1010
prelude::lookup::TYPE,
1111
types::Type,
12+
value::Value,
1213
};
1314

1415
pub mod opcode {
@@ -190,12 +191,12 @@ impl CompileTimeEnv {
190191
pub struct ExprByteCode {
191192
version: [u8; 4],
192193
codes: Vec<u8>,
193-
strings: Vec<String>,
194+
constants: Vec<Value>,
194195
types: Vec<Type>,
195196
}
196197

197198
impl ExprByteCode {
198-
pub fn new(codes: Vec<u8>, strings: Vec<String>, types: Vec<Type>) -> Self {
199+
pub fn new(codes: Vec<u8>, constants: Vec<Value>, types: Vec<Type>) -> Self {
199200
let version_bytes = get_version_bytes();
200201
let version_bytes_from_codes = &codes[0..4];
201202

@@ -209,7 +210,7 @@ impl ExprByteCode {
209210
Self {
210211
version: version_bytes,
211212
codes,
212-
strings,
213+
constants,
213214
types,
214215
}
215216
}
@@ -226,8 +227,8 @@ impl ExprByteCode {
226227
self.codes.get(index)
227228
}
228229

229-
pub fn strings(&self) -> &[String] {
230-
&self.strings
230+
pub fn constants(&self) -> &[Value] {
231+
&self.constants
231232
}
232233

233234
pub fn types(&self) -> &[Type] {
@@ -246,21 +247,21 @@ pub fn get_version_bytes() -> [u8; 4] {
246247

247248
/// Compile an [`ast::Expr`] into [`ExprByteCode`]
248249
pub fn compile(expr: &mut ExprS, env: &CompileTimeEnv) -> ExprResult<ExprByteCode> {
249-
let mut strings: Vec<String> = vec![];
250+
let mut constants: Vec<Value> = vec![];
250251
let mut types: Vec<Type> = vec![];
251252
let mut codes = vec![];
252253

253254
codes.extend(get_version_bytes());
254255

255-
codes.extend(compile_expr(expr, env, &mut strings, &mut types)?);
256+
codes.extend(compile_expr(expr, env, &mut constants, &mut types)?);
256257

257-
Ok(ExprByteCode::new(codes, strings, types))
258+
Ok(ExprByteCode::new(codes, constants, types))
258259
}
259260

260261
fn compile_expr(
261262
(expr, span): &mut ExprS,
262263
env: &CompileTimeEnv,
263-
strings: &mut Vec<String>,
264+
constants: &mut Vec<Value>,
264265
types: &mut Vec<Type>,
265266
) -> ExprResult<Vec<u8>> {
266267
use opcode::*;
@@ -272,12 +273,18 @@ fn compile_expr(
272273

273274
match expr {
274275
Expr::String(string) => {
275-
if let Some(index) = strings.iter().position(|x| x == &string.0) {
276+
if let Some(index) = constants.iter().position(|x| {
277+
if let Value::String(string_constant) = x {
278+
string_constant == &string.0
279+
} else {
280+
false
281+
}
282+
}) {
276283
codes.push(CONSTANT);
277284
codes.push(index as u8);
278285
} else {
279-
strings.push(string.0.clone());
280-
let index = strings.len() - 1;
286+
constants.push(Value::String(string.0.clone()));
287+
let index = constants.len() - 1;
281288
codes.push(CONSTANT);
282289
codes.push(index as u8);
283290
}
@@ -356,7 +363,7 @@ fn compile_expr(
356363
}
357364
}
358365
Expr::Call(expr_call) => {
359-
let callee_bytecode = compile_expr(&mut expr_call.callee, env, strings, types)?;
366+
let callee_bytecode = compile_expr(&mut expr_call.callee, env, constants, types)?;
360367

361368
if let Some(_op) = callee_bytecode.first()
362369
&& let Some(lookup) = callee_bytecode.get(1)
@@ -433,7 +440,7 @@ fn compile_expr(
433440
codes.extend(callee_bytecode);
434441

435442
for arg in expr_call.args.iter_mut() {
436-
match compile_expr(arg, env, strings, types) {
443+
match compile_expr(arg, env, constants, types) {
437444
Ok(arg_bytecode) => {
438445
codes.extend(arg_bytecode);
439446
}

src/disassembler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ impl<'bytecode, 'env> Disassembler<'bytecode, 'env> {
9595

9696
let value = self
9797
.bytecode
98-
.strings()
98+
.constants()
9999
.get(constant_idx)
100-
.expect("should have string at index");
100+
.expect("should have value in constants at index");
101101

102102
let string = format!("{name:16} {constant_idx:>4} == '{value}'\n");
103103

src/vm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,11 @@ impl Vm {
195195
.bytecode
196196
.as_ref()
197197
.expect("should have bytecode")
198-
.strings()
198+
.constants()
199199
.get(get_idx)
200200
.unwrap_or_else(|| panic!("undefined string: {}", get_idx));
201201

202-
self.stack_push(Value::String(s.clone()));
202+
self.stack_push(s.clone());
203203

204204
Ok(())
205205
}

tests/integration_tests.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ mod valid {
236236
crate::make_test_bytecode(vec![
237237
opcode::CONSTANT, 0
238238
]),
239-
vec!["test string".to_string()],
239+
vec![Value::String("test string".to_string())],
240240
vec![]
241241
));
242242

243-
disassembles to: "VERSION 0800\n----\n0000 CONSTANT 0 == 'test string'\n";
243+
disassembles to: "VERSION 0800\n----\n0000 CONSTANT 0 == '`test string`'\n";
244244

245245
runtime env: {
246246
..Default::default()
@@ -391,12 +391,12 @@ mod valid {
391391
opcode::CALL, 1
392392
]),
393393
vec![
394-
"test value".to_string(),
394+
Value::String("test value".to_string()),
395395
],
396396
vec![]
397397
));
398398

399-
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 0 == 'id'\n0003 CONSTANT 0 == 'test value'\n0005 CALL (1 args)\n";
399+
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 0 == 'id'\n0003 CONSTANT 0 == '`test value`'\n0005 CALL (1 args)\n";
400400

401401
runtime env: {
402402
..Default::default()
@@ -1300,13 +1300,13 @@ mod valid {
13001300
opcode::CALL, 3
13011301
]),
13021302
vec![
1303-
"foo".to_string(),
1304-
"bar".to_string(),
1303+
Value::String("foo".to_string()),
1304+
Value::String("bar".to_string()),
13051305
],
13061306
vec![]
13071307
));
13081308

1309-
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 5 == 'cond'\n0003 TRUE\n0004 CONSTANT 0 == 'foo'\n0006 CONSTANT 1 == 'bar'\n0008 CALL (3 args)\n";
1309+
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 5 == 'cond'\n0003 TRUE\n0004 CONSTANT 0 == '`foo`'\n0006 CONSTANT 1 == '`bar`'\n0008 CALL (3 args)\n";
13101310

13111311
runtime env: {
13121312
..Default::default()
@@ -1353,13 +1353,13 @@ mod valid {
13531353
opcode::CALL, 3
13541354
]),
13551355
vec![
1356-
"foo".to_string(),
1357-
"bar".to_string(),
1356+
Value::String("foo".to_string()),
1357+
Value::String("bar".to_string()),
13581358
],
13591359
vec![]
13601360
));
13611361

1362-
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 5 == 'cond'\n0003 FALSE\n0004 CONSTANT 0 == 'foo'\n0006 CONSTANT 1 == 'bar'\n0008 CALL (3 args)\n";
1362+
disassembles to: "VERSION 0800\n----\n0000 GET BUILTIN 5 == 'cond'\n0003 FALSE\n0004 CONSTANT 0 == '`foo`'\n0006 CONSTANT 1 == '`bar`'\n0008 CALL (3 args)\n";
13631363

13641364
runtime env: {
13651365
..Default::default()

0 commit comments

Comments
 (0)