Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for globals. #90

Merged
merged 1 commit into from
Feb 7, 2020
Merged

Conversation

ummarikar
Copy link
Collaborator

@ummarikar ummarikar commented Jan 15, 2020

Add a hashmap which maps symbols to their corresponding object and retrieve an object from this hashmap when its symbol is referenced during runtime.

@ummarikar
Copy link
Collaborator Author

This PR is unfinished and is only "fully" implemented for the Integer class, just wanted to submit it so we can discuss my implementation before I finish the rest and subsequently squash. FYI the test passes.

src/lib/vm/core.rs Outdated Show resolved Hide resolved
@ltratt
Copy link
Member

ltratt commented Jan 15, 2020

yksom currently doesn't handle globals in an ideal way in the sense that they can't be reassigned to (which, I think, SOM allows). Before we go down the full class primitives route, we should probably get the semantics of this right because we may then be able to merge / remove the Builtin opcode which currently does something very similar to what you've called Globals.

@ummarikar
Copy link
Collaborator Author

How do you think we should do it?

@ltratt
Copy link
Member

ltratt commented Jan 15, 2020

I think you should make some test files that show what happens in other SOMs when you assign to a global, and then see how such behaviour might best be implemented in yksom.

@ummarikar
Copy link
Collaborator Author

By assigning globals do you mean what was discussed here? #82 (comment)

@ltratt
Copy link
Member

ltratt commented Jan 15, 2020

Yes, but there might be other ways of doing the same thing too (e.g. assigning to the variable Integer or true might work for all I know).

@ummarikar
Copy link
Collaborator Author

Great I'll start that now and will let you know how I get on.

@smarr
Copy link
Contributor

smarr commented Jan 15, 2020

@ummarikar please try all the things you can come up with, especially the things that should not work... I am, well, not entirely sure which cases are handled correctly...

Via system one can definitely change the globals. Using a simple assignment, I would hope not, but oh well...

@ummarikar
Copy link
Collaborator Author

@ummarikar please try all the things you can come up with, especially the things that should not work... I am, well, not entirely sure which cases are handled correctly...

Via system one can definitely change the globals. Using a simple assignment, I would hope not, but oh well...

Will do! Thanks

@ummarikar
Copy link
Collaborator Author

Working on global:put: as I am typing this, just wanted to submit what I have done thus far so it can be critiqued.

@ltratt
Copy link
Member

ltratt commented Jan 18, 2020

I think we really need to see "hard" examples (as @smarr suggested) before critiquing the code, as the precise SOM semantics could change what we perceive to be the best route.

@ummarikar
Copy link
Collaborator Author

Yes apologies, I’ve been working on something substantial but have hit a couple of roadblocks along the way. Will submit something either today or tomorrow.

@ummarikar
Copy link
Collaborator Author

Still struggling to get this right don’t want to ask for help yet though so I will continue to try

lang_tests/system3.som Outdated Show resolved Hide resolved
src/lib/vm/core.rs Outdated Show resolved Hide resolved
@ummarikar
Copy link
Collaborator Author

ummarikar commented Jan 25, 2020

@smarr what are the intended semantics for (System global: #Integer put: 42) println.? Does global:put: return anything such as the value you give it (42 in this case)?

@ummarikar
Copy link
Collaborator Author

ummarikar commented Jan 25, 2020

Ignore me I had a look at the code for global:put: in som-java and referred to the comment you left here - #82 (comment) and found that it returns nothing.

@smarr
Copy link
Contributor

smarr commented Jan 25, 2020

@ummarikar hm, I think this is a good question.
I believe it is common practice to return either self or the value from such mutating methods.

See for instance: (Array new: 6) at: 4 put: 66, which returns 66.

I would assume that returning the value is the most useful thing to do here,
given the #at:put: precedence, and that the value may be derived from an expression.
Returning system or nil seems not ideal.

@ummarikar
Copy link
Collaborator Author

ummarikar commented Jan 25, 2020

@smarr I agree! I’ll have global:put: return value.

src/lib/vm/core.rs Outdated Show resolved Hide resolved
src/lib/vm/core.rs Outdated Show resolved Hide resolved
@ummarikar
Copy link
Collaborator Author

ummarikar commented Jan 28, 2020

This is my global: and global:put: solution. I have changed the name of the tests too so they are more descriptive.

@ummarikar
Copy link
Collaborator Author

Just added the classes of som to ast_to_instrs.

@ltratt
Copy link
Member

ltratt commented Jan 28, 2020

Before I look into this in detail, can I check that you've run all the new tests on another SOM (e.g. Java SOM) to check that they behave exactly the same?

@ummarikar
Copy link
Collaborator Author

I tried this in SOM but I got an error that global: and global:put: is not in the System class. Will try it in another SOM soon.

lang_tests/system_global.som Outdated Show resolved Hide resolved
lang_tests/system_global_invalid_symbol_err.som Outdated Show resolved Hide resolved
lang_tests/system_global_put_invalid_symbol_err.som Outdated Show resolved Hide resolved
lang_tests/system_global_put_type_err.som Outdated Show resolved Hide resolved
@ummarikar
Copy link
Collaborator Author

Okay now that @smarr kindly, pointed out that I have been mistaking System for system I have run tests on java SOM and I believe I understand the semantics now. Please ignore my code above and I will start working on the changes.

@smarr
Copy link
Contributor

smarr commented Feb 6, 2020

I am not sure why the boolean is necessary. And I do not understand the logic where the boolean is tested.

In other SOM implementations, this boolean doesn't seem to be necessary. Metaclasses are also just instances of Class.

---> Integer class class superclass println
Class

Again, your PR is growing :) So, perhaps this is fine for the moment, but probably wants to be looked at at a later time again.

@ltratt
Copy link
Member

ltratt commented Feb 6, 2020

I agree with @smarr that we need to get this PR to a resolution. It's partly my fault for asking questions.

@ummarikar I suggest splitting this PR into two. Let's make this PR everything before the "adding metaclass" commit. You can do something like git checkout -b metaclass ; git checkout class_primitivies; get reset --hard 4e538bc719 to do this. Then we can work out what we need to do to fix the pre-metaclass stuff. Maybe the simplest correct thing is to just delete that int_class test that was causing us confusion? Once we've got this PR to a point we're happy with, we can then move on to the actual metaclass PR.

@ummarikar
Copy link
Collaborator Author

Done

false
"

system_global = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To double check: does this test run identically on another SOM?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything except the last three lines but per @smarr 's request we kept nil, true and false as non-globals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, got it.


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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As elsewhere, we can't (generally) safely assign UnsafeCells to a variable, so unless we really need to, let's not do so.

In this case, we can probably change the code below to something like: unsafe { &mut *self.globals.get() }.entry(&idx).and_modify(|e| *e = val) (notice that I think the Inst::new is still bogus, right?).

@@ -326,6 +343,15 @@ impl VM {
unsafe { &mut *self.stack.get() }.push(Double::new(self, i));
pc += 1;
}
Instr::Global(symbol_off) => {
debug_assert!(unsafe { &*self.symbols.get() }.len() > symbol_off);
if let Some(global) = unsafe { &mut *self.globals.get() }.get(&symbol_off) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably do the entry trick here too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no, ignore that comment -- sorry!


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.clone());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that the second clone is unnecessary, but I might be wrong.

@ummarikar
Copy link
Collaborator Author

Done.

let idx = self.add_symbol(name.to_string());
unsafe { &mut *self.globals.get() }
.entry(idx)
.or_insert(val.clone());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and_modify did not pass the tests but this does.

match lex_string {
"nil" => vm.instrs_push(Instr::Builtin(Builtin::Nil)),
"false" => vm.instrs_push(Instr::Builtin(Builtin::False)),
"system" => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this clause unnecessary in the sense that it's covered by the _ clause below?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, must have forgotten to remove it. Done now

@ltratt
Copy link
Member

ltratt commented Feb 7, 2020

Please squash.

@ummarikar ummarikar force-pushed the class_primitives branch 2 times, most recently from f86e586 to 66c8704 Compare February 7, 2020 18:28
@@ -44,6 +44,8 @@ pub enum VMError {
expected: ObjType,
got: ObjType,
},
/// Tried to access a global before it being initialised.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment that was here before was incorrect so I changed it to this. Everything is squashed now!

@ltratt
Copy link
Member

ltratt commented Feb 7, 2020

Should these 3 commits be squashed down into 1? The last commit seems to fix fairly big problems in the first 1 or 2 commits, so I'm not sure those are very useful to keep in the history. However, I can be convinced otherwise.

@ummarikar
Copy link
Collaborator Author

You make a very good point I'll squash this into one.

@ummarikar
Copy link
Collaborator Author

Squashed.

@ltratt
Copy link
Member

ltratt commented Feb 7, 2020

Would I be right in thinking that the commit title should really be "add support for globals"?

@ummarikar
Copy link
Collaborator Author

Yes you would, one second.

Add a hashmap which maps symbols to their corresponding object and retrieve an object from this hashmap when its symbol is referenced during runtime.
@ummarikar
Copy link
Collaborator Author

Done :)

@ummarikar ummarikar changed the title Add support for class primitives. Add support for globals. Feb 7, 2020
@ltratt
Copy link
Member

ltratt commented Feb 7, 2020

bors r+

bors bot added a commit that referenced this pull request Feb 7, 2020
90: Add support for globals. r=ltratt a=ummarikar

Add a hashmap which maps symbols to their corresponding object and retrieve an object from this hashmap when its symbol is referenced during runtime.

Co-authored-by: Umar Marikar <[email protected]>
@bors
Copy link
Contributor

bors bot commented Feb 7, 2020

Build succeeded

@bors bors bot merged commit 3c0ce78 into softdevteam:master Feb 7, 2020
@ummarikar ummarikar deleted the class_primitives branch February 12, 2020 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants