Skip to content

Commit

Permalink
Add global:put: primitive to the System class.
Browse files Browse the repository at this point in the history
`global:put:` should return value.

Add errors for `global:put:`.
  • Loading branch information
ummarikar committed Feb 7, 2020
1 parent 547d7f2 commit 66c8704
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 60 deletions.
8 changes: 4 additions & 4 deletions lang_tests/instance_vars2.som
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
VM:
status: error
stderr:
...line 11, column 11:
...
Unknown variable 'x'
InvalidSymbol
"

instance_vars2 = (
x = (^x)
run = (
x = 1
)
)
12 changes: 0 additions & 12 deletions lang_tests/int_class.som

This file was deleted.

12 changes: 0 additions & 12 deletions lang_tests/system3.som

This file was deleted.

36 changes: 36 additions & 0 deletions lang_tests/system_global.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"
VM:
status: success
stdout:
true
true
42
42
String
21
21
nil
true
false
"

system_global = (
run = (
((system global: #Integer) == Integer) println.
system global: #Integer put: 42.
((system global: #Integer) == Integer) println.
Integer println.
(system global: #Integer) println.
system global: #Integer put: 'a'.
Integer class println.
system global: #ab put: 21.
(system global: #ab) println.
ab println.
system global: #nil put: 'a'.
system global: #true put: 'b'.
system global: #false put: 'c'.
nil println.
true println.
false println.
)
)
11 changes: 11 additions & 0 deletions lang_tests/system_global_invalid_symbol_err.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"
VM:
status: error
stderr: InvalidSymbol
"

system_global_invalid_symbol_err = (
run = (
system global: #ab.
)
)
5 changes: 3 additions & 2 deletions lib/SOM/System.som
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
System = (
global: name = primitive
printString: string = primitive
printNewline = primitive
global: name put: value = primitive
printString: string = primitive
printNewline = primitive
)
26 changes: 14 additions & 12 deletions src/lib/compiler/ast_to_instrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impl<'a> Compiler<'a> {
"class" => Ok(MethodBody::Primitive(Primitive::Class)),
"concatenate:" => Ok(MethodBody::Primitive(Primitive::Concatenate)),
"global:" => Ok(MethodBody::Primitive(Primitive::Global)),
"global:put:" => Ok(MethodBody::Primitive(Primitive::GlobalPut)),
"halt" => Ok(MethodBody::Primitive(Primitive::Halt)),
"hashcode" => Ok(MethodBody::Primitive(Primitive::Hashcode)),
"inspect" => Ok(MethodBody::Primitive(Primitive::Inspect)),
Expand Down Expand Up @@ -486,19 +487,20 @@ impl<'a> Compiler<'a> {
vm.instrs_push(Instr::VarLookup(depth, var_num));
}
}
Err(e) => match self.lexer.lexeme_str(&lexeme) {
"nil" => vm.instrs_push(Instr::Builtin(Builtin::Nil)),
"false" => vm.instrs_push(Instr::Builtin(Builtin::False)),
"system" => vm.instrs_push(Instr::Builtin(Builtin::System)),
"true" => vm.instrs_push(Instr::Builtin(Builtin::True)),
"Integer" => {
vm.instrs_push(Instr::Global(vm.add_symbol("Integer".to_string())))
}
"System" => {
vm.instrs_push(Instr::Global(vm.add_symbol("System".to_string())))
Err(_) => {
let lex_string = self.lexer.lexeme_str(&lexeme);

match lex_string {
"nil" => vm.instrs_push(Instr::Builtin(Builtin::Nil)),
"false" => vm.instrs_push(Instr::Builtin(Builtin::False)),
"true" => vm.instrs_push(Instr::Builtin(Builtin::True)),
_ => {
vm.instrs_push(Instr::Global(
vm.add_symbol(lex_string.to_string()),
));
}
}
_ => return Err(e),
},
}
}
Ok(1)
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/compiler/instrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub enum Primitive {
DoubleDiv,
Equals,
Global,
GlobalPut,
GreaterThan,
GreaterThanEquals,
Halt,
Expand Down
49 changes: 31 additions & 18 deletions src/lib/vm/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub enum VMError {
expected: ObjType,
got: ObjType,
},
/// Tried to access a global before it being initialised.
InvalidSymbol,
/// Tried to do a shl or shr with a value below zero.
NegativeShift,
/// A specialised version of TypeError, because SOM has more than one number type (and casts
Expand Down Expand Up @@ -169,7 +171,6 @@ impl VM {
reverse_symbols: UnsafeCell::new(HashMap::new()),
frames: UnsafeCell::new(Vec::new()),
};

// The very delicate phase.
//
// Nothing in this phase must store references to the nil object or any classes earlier
Expand All @@ -193,6 +194,10 @@ impl VM {
vm.sym_cls = vm.init_builtin_class("Symbol", false);
vm.system_cls = vm.init_builtin_class("System", false);
vm.true_cls = vm.init_builtin_class("True", false);
unsafe { &mut *vm.globals.get() }.insert(
vm.add_symbol("system".to_string()),
Inst::new(&vm, vm.system_cls.clone()),
);
vm.false_ = Inst::new(&vm, vm.false_cls.clone());
vm.system = Inst::new(&vm, vm.system_cls.clone());
vm.true_ = Inst::new(&vm, vm.true_cls.clone());
Expand Down Expand Up @@ -231,11 +236,9 @@ impl VM {

let val = self.compile(&path, inst_vars_allowed);
let idx = self.add_symbol(name.to_string());
let globals = unsafe { &mut *self.globals.get() };

if !globals.get(&idx).is_some() {
globals.insert(idx, Inst::new(self, val.clone()));
}
unsafe { &mut *self.globals.get() }
.entry(idx)
.or_insert(val.clone());

val
}
Expand Down Expand Up @@ -339,12 +342,11 @@ impl VM {
}
Instr::Global(symbol_off) => {
debug_assert!(unsafe { &*self.symbols.get() }.len() > symbol_off);
unsafe { &mut *self.stack.get() }.push(
unsafe { &mut *self.globals.get() }
.get(&symbol_off)
.unwrap_or_else(|| panic!("Could not find global."))
.clone(),
);
if let Some(global) = unsafe { &mut *self.globals.get() }.get(&symbol_off) {
unsafe { &mut *self.stack.get() }.push(global.clone());
} else {
return SendReturn::Err(Box::new(VMError::InvalidSymbol));
}
pc += 1;
}
Instr::InstVarLookup(n) => {
Expand Down Expand Up @@ -500,17 +502,28 @@ impl VM {
SendReturn::Val
}
Primitive::Global => {
let v = unsafe { &mut *self.stack.get() }.pop();
let reverse_symbols = unsafe { &mut *self.reverse_symbols.get() };
let globals = unsafe { &mut *self.globals.get() };
let as_string: &String_ = stry!(v.downcast(self));
let name = unsafe { &mut *self.stack.get() }.pop();
let as_string: &String_ = stry!(name.downcast(self));
let s = as_string.as_str();

if let Some(i) = reverse_symbols.get(s) {
if let Some(val) = globals.get(&i) {
if let Some(i) = unsafe { &mut *self.reverse_symbols.get() }.get(s) {
if let Some(val) = unsafe { &mut *self.globals.get() }.get(&i) {
unsafe { &mut *self.stack.get() }.push(val.clone());
return SendReturn::Val;
}
}
SendReturn::Err(Box::new(VMError::InvalidSymbol))
}
Primitive::GlobalPut => {
let value = unsafe { &mut *self.stack.get() }.pop();
let name = unsafe { &mut *self.stack.get() }.pop();
let as_string: &String_ = stry!(name.downcast(self));
let s = as_string.as_str();

if let Some(i) = unsafe { &mut *self.reverse_symbols.get() }.get(s) {
unsafe { &mut *self.globals.get() }.insert(*i, value.clone());
unsafe { &mut *self.stack.get() }.push(value);
}
SendReturn::Val
}
Primitive::GreaterThan => {
Expand Down

0 comments on commit 66c8704

Please sign in to comment.