chenhsi / Ambroscum

An interpreter/compiler for a programming language we're probably going to create
MIT License
0 stars 0 forks source link

Call expressions with dynamic function #19

Closed edgao closed 10 years ago

edgao commented 10 years ago
def fn(x):
    return x
end
val = {100: fn}[100](5)

Obviously, the expected result is that val = 5, but this currently fails - ExpressionCall never gets used, since the program sees the dictionary and just uses ExpressionReference to parse (which obviously means that the parentheses never get read).

chenhsi commented 10 years ago

The issue in general seems to be that most expressions aren't expecting to be followed by any sort of reference or call; for example, "string"[3] doesn't work either (and not because we aren't supporting list-style references for strings).

I think that the fix would be to move dealing with recursive references out of Expression.greedy, and simply check after the Expression.greedy call to examine the next token for any sort of referencing (i.e. ".", "(", "[", or "{") in whatever calls it (currently Expression.interpret, but I can see an argument for putting another function call in between). The current code for dealing with recursive ExpressionReferences could also be moved.

I'm not currently awake enough to decide on the possible ramifications of this, nor am I willing to spend the effort to understand how you currently have ExpressionReferences set up and to change it, so if this is understandable and sounds like it works to you, I'll try changing the non-ExpressionReferences part tomorrow.

chenhsi commented 10 years ago

Made most of the changes, but the second ExpressionReference constructor completely fails right now; I"ll probably figure out how the fields work tomorrow.

edgao commented 10 years ago

I"m honestly tempted to just nix ExpressionReference almost entirely - it's grown to something way too unwieldy. Probably the only construct it should be handling is something like expression[index or key].

Basically, what I'm envisioning for the procedure is: (e.g. for the expresion [[fn, 2, 3], 4, 5, {5: 6}[5]][0][0]() (assuming fn is a function, of course)

  1. Expression.interpret() is called
  2. It parses out the first expression - in this case, [[fn, 2, 3], 4, 5, {5: 6}[6]], which is interpreted as an ExpressionList (which, in turn, is going to contain other Expressions - these are parsed recursively)
  3. while (stream.peek is something that needs to be chained with the current Expression - e.g. indexing, dereferencing, calling): Expression calls the appropriate thing. In the example, it creates two ExpressionReferences (for the two [0]) and then an ExpressionCall (for the ()).

I'll be creating a new branch for this, since it's going to diverge significantly from what we have right now. Hopefully, I can get some basic stuff working by tonight.

chenhsi commented 10 years ago

Welp, just as I committed breaking up ExpressionReference; I gave up on you responding before school started again. My lists don't work properly though (I think it's something to do with how lists are passed around and accessed), which I"ll figure out tomorrow, probably.

edgao commented 10 years ago

Sigh. I guess this is what I get for derping so hard. Do you want me to help out on this, or should I work on other stuff?

chenhsi commented 10 years ago

If you want to fix the current problem with Lists/Dicts (or so I presume), that would be great, or you could work on other stuff too (actually, if you could reply to my comments on some of the other issues, that would be even better); I probably won't be back to working on this until tomorrow afternoon, so either way, we won't be conflicting.

chenhsi commented 10 years ago

All current test cases pass (well, except the one about maps, but that's unrelated), and the code in the OP gets evaluated correctly, so I'm closing this issue for now.