Skip to content

Commit 7271988

Browse files
committed
Merge branch 'this'
2 parents 116ba28 + 14174a5 commit 7271988

File tree

7 files changed

+163
-18
lines changed

7 files changed

+163
-18
lines changed

examples/class.zen

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@ mod stdlib;
33
// ZenLang is not object oriented - therefore it doesn't have classes
44
// But you can make something similar
55
fn class_new {
6-
let inst = {"a" = 0, "b" = 0};
7-
return inst;
6+
return {
7+
"add_a" = class_add_a,
8+
"add_b" = class_add_b,
9+
"print" = class_print,
10+
"a" = 0,
11+
"b" = 0
12+
};
813
}
914

10-
fn class_add_a self n {
15+
fn class_add_a n {
1116
let self.a = self.a + n;
1217
return null;
1318
}
1419

15-
fn class_add_b self n {
20+
fn class_add_b n {
1621
let self.b = self.b + n;
1722
return null;
1823
}
1924

20-
fn class_print self {
25+
fn class_print {
2126
let res = self.a + self.b;
2227
println(res);
2328
return null;
2429
}
2530

2631
fn main {
2732
let class = class_new();
28-
class_add_a(class, 42);
29-
class_add_b(class, 69);
30-
class_print(class);
33+
class.add_a(42);
34+
class.add_b(69);
35+
class.print();
3136
return null;
3237
}

examples/stack.zen

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
mod stdlib;
22

33
fn stack_new {
4-
return {"data" = []};
4+
return {
5+
"top" = stack_top,
6+
"push" = stack_push,
7+
"pop" = stack_pop,
8+
"size" = stack_size,
9+
"is_empty" = stack_is_empty,
10+
"data" = []
11+
};
512
}
613

7-
fn stack_top self {
14+
fn stack_top {
815
return array_last(self.data);
916
}
1017

11-
fn stack_push self element {
18+
fn stack_push element {
1219
let self.data = array_push(self.data, element);
1320
return null;
1421
}
1522

16-
fn stack_pop self {
23+
fn stack_pop {
1724
let self.data = array_pop(self.data);
1825
return null;
1926
}
2027

21-
fn stack_size self {
28+
fn stack_size {
2229
return array_size(self.data);
2330
}
2431

25-
fn stack_is_empty self {
26-
return stack_size(self) == 0;
32+
fn stack_is_empty {
33+
return self.size() == 0;
2734
}
2835

2936
fn main {
3037
let stack = stack_new();
31-
stack_push(stack, 69);
32-
println(stack_top(stack));
33-
return stack_is_empty(stack);
38+
stack.push(69);
39+
println(stack.top());
40+
return stack.is_empty();
3441
}

zenlang/src/value.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,9 @@ impl Display for Value {
201201
}
202202
}
203203
}
204+
205+
impl Default for Value {
206+
fn default() -> Self {
207+
return Value::Null();
208+
}
209+
}

zenlang/src/vm/opcodes/vm_call.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::strong_u64::U64BitsControl;
22
use crate::value::*;
33
use crate::vm::VM;
44
use alloc::format;
5+
use alloc::string::*;
56

67
impl VM {
78
pub fn op_call(&mut self) {
@@ -13,6 +14,11 @@ impl VM {
1314
self.pc.sub_low(1);
1415
self.add_scope();
1516

17+
let this_name = &String::from("self");
18+
let scope = self.scopes.last_mut().unwrap();
19+
scope.create_if_doesnt_exist(this_name);
20+
*scope.get_mut(this_name).unwrap() = core::mem::take(&mut self.self_var);
21+
1622
let start = self.bfas_stack_start.pop().unwrap();
1723
let end = self.bfas_stack_end.pop().unwrap();
1824
let diff = end - start;

zenlang/src/vm/opcodes/vm_iafs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ impl VM {
1919
self.error = format!("iafs failed: no more values on stack for array");
2020
return;
2121
}
22+
self.self_var = array.clone();
2223

2324
match array {
2425
Value::Object(obj) => match &*obj.borrow() {

zenlang/src/vm/vm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct VM {
2121
pub platform: Option<Box<dyn Platform>>,
2222
pub global_scope: Scope,
2323
pub halted: bool,
24+
pub self_var: Value,
2425
pub(crate) bfas_stack_start: Vec<i64>,
2526
pub(crate) bfas_stack_end: Vec<i64>,
2627
}
@@ -38,6 +39,7 @@ impl VM {
3839
platform: None,
3940
global_scope: Scope::new(),
4041
halted: false,
42+
self_var: Value::Null(),
4143
bfas_stack_start: Vec::new(),
4244
bfas_stack_end: Vec::new(),
4345
};

zenlang/tests/vm_self.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
extern crate alloc;
2+
3+
use zenlang::compiler::*;
4+
use zenlang::parser::*;
5+
use zenlang::tokenizer::*;
6+
use zenlang::value::*;
7+
use zenlang::vm::*;
8+
9+
fn expect_to_return(code: String, value: Value) {
10+
let mut tokenizer = Tokenizer::new(code);
11+
let mut parser = Parser::new(&mut tokenizer);
12+
let mut compiler = Compiler::new(&mut parser);
13+
if let Err(e) = compiler.compile() {
14+
assert_eq!(e, "");
15+
}
16+
let mut vm = VM::new();
17+
let module = compiler.get_module();
18+
println!("{:?}", module.opcodes);
19+
20+
let _ = vm.load_module(&zenlang::stdlib::compile_stdlib_module());
21+
let _ = vm.load_module(module);
22+
23+
if let Err(e) = vm.set_entry_function("main") {
24+
assert_eq!(e, "");
25+
}
26+
27+
vm.run_until_halt();
28+
29+
println!("vm.ret: {:?}", vm.ret);
30+
assert_eq!(vm.error, "");
31+
assert!(vm.ret.equal(&value, &vm));
32+
}
33+
34+
#[test]
35+
fn vm_test_self_1() {
36+
expect_to_return(
37+
r#"
38+
fn f2 {
39+
let self.hi = self.hi + 3;
40+
}
41+
42+
fn f {
43+
let self.hi = 1;
44+
self.test2();
45+
}
46+
47+
fn main {
48+
let obj = {
49+
"test" = f,
50+
"test2" = f2,
51+
};
52+
obj.test();
53+
return obj.hi;
54+
} "#
55+
.into(),
56+
Value::Number(4.0),
57+
);
58+
}
59+
60+
#[test]
61+
fn vm_test_self_2() {
62+
expect_to_return(
63+
r#"
64+
fn f2 {
65+
let self.hi = 3;
66+
}
67+
68+
fn f {
69+
let self.hi = 1;
70+
let obj = {
71+
"test" = f2
72+
};
73+
obj.test();
74+
let self.hi = obj.hi - 1;
75+
}
76+
77+
fn main {
78+
let obj = {
79+
"test" = f,
80+
};
81+
obj.test();
82+
return obj.hi;
83+
} "#
84+
.into(),
85+
Value::Number(2.0),
86+
);
87+
}
88+
89+
#[test]
90+
fn vm_test_self_3() {
91+
expect_to_return(
92+
r#"
93+
fn f2 {
94+
let self.hi = 3;
95+
}
96+
97+
fn f {
98+
let self.hi = 1;
99+
let obj = {
100+
"test" = f2
101+
};
102+
obj.test();
103+
let self.hi = obj.hi - 1;
104+
}
105+
106+
fn main {
107+
let obj = {
108+
"obj" = {
109+
"test" = f,
110+
}
111+
};
112+
obj.obj.test();
113+
return obj.obj.hi;
114+
} "#
115+
.into(),
116+
Value::Number(2.0),
117+
);
118+
}

0 commit comments

Comments
 (0)