-
Notifications
You must be signed in to change notification settings - Fork 0
/
evalRef-notes.txt
110 lines (77 loc) · 5.62 KB
/
evalRef-notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
-- | 'this' in a function still refers to global
-- | this when the calling function is a property of an object refers to
-- | The encasing Object, ***even if it's not derived from a template
-- | This could also be used with VarDecl ~ Raw Op [Name], at least for getsAST
-- | ALL AST Directly
-- | How to handle if we are in a function?
-- | TODO(galen): factor out Chaining
-- | Instead: we should check if there's an entry for 'this' as an object
-- | Exists -> we are in an object, so this refers to a prop of this object
-- | meaning we are in a property function, so this can only refer to the mInnerScope
-- | and mInnerScope must be (Just ast) or we've done something stupid: evalFunc doesn't work
-- | properly
-- | !Exists -> we are not in an object
-- | in this case it could only come from global
-- also make sure that we return the object when we eval a propertyFunction
-- then we are verifiably not in a propertyFunction (or we have invalid code)
-- since running a propertyFunction should handle setting 'this'
-- case lookupAST nameChain astI of
-- Just
-- Nothing -> ""
-- lookupGlobal -- can only be from global
-- could i handle this as a special case?
-- we can only chain on objects and only objects can have 'this'
-- we could perhaps turn all fields of the record into attributes under 'this'
-- so if we do this strategy then we also need to include super
-- | So the thing about Objects is there are the ones that are derived from a class
-- | and ones derived from an expression
-- | Both will have fields that are reduced to ExprAST
-- | the variation is in the functions where the functions may call either super.<someFunctionWhichMayHaveNameConflict>() {refs to vars from its constructor (available by 'this'} or this.field
-- | the only problem with this approach is that the 'this' keyword can happen anywhere
-- | obj.a is only available either by literally obj.a or this.a
-- | chaining is specifically for ObjectOriented ("", {}, fn)
-- | This yields yet another problem:
-- | this will return an Expr which is valid here, but what do we with the changed inner state?
-- | because we don't know if it's even reference-able itself
-- | ..wait
-- | if we have the name (or nameChain prefix) of the calling function, we can handle this
-- | eg:
-- | class Chainerr { constructor() {this.x = 1} iter() { this.x += 1; return 7 }}
-- | c = new Chainer
-- | c.iter() --> (Return 7, c.x = 1 + 1)
-- | c.iter() --> (Return 7, c.x = 1 + 1 + 1)
-- | AND
-- | c.d = new Chainerr
-- | c.d.iter() -- c.d is what is affected
-- | But whats awesome here: is that this solution also solves how to handle the odd
-- | case of window.doSomething() as we know handle memory properly in cases
-- | where we are not simply using an equals sign or the like
-- | This therefore means that we can expect to handle all cases
-- will this work for more complex cases?
-- eg. x.f().y.z() .... i mean probably right? cuz result of z is deleted/not retained?
-- but we actually dont know that we will handle that properly
-- we can gurantee this if before we handle .y.z() we set the new value of x resulting from
-- the application of f()
-- Also based on the error: Uncaught TypeError: Cannot read properties of undefined (reading 'x')
-- its very safe to say that '.p' means of returned, get property p NOT some second execution
-- of the base object
-- the best way to handle this is to completely deref an object upon instantiation (where this class def gets called)
-- at this time we have a name (or we dont and we just call the constructor with a fake name)
-- Once we have a name:
-- this.x --> name.x
-- so we should parse this class, create an object (where this still exists) then call deThis
--- OTHER NOTES
--What if instead we had
-- | For control ones, we don't need or even want to know dependencies at this level
-- | For Functions and Classes we do special scoping where when we check dependencies
-- | We first check if the function defined the var name
-- | And prefer the innermost scope (for multiple functions)
-- | (function (x) { var x = 2; return ((function(x){return x})(10))})(1) ---> Returns 10 NOT(2,1)
-- | `this` is a synonym for the outer object (?)
-- | best way to set this up is to allow infinite recursion (and therefore also simple lookups)
-- | and then check if its a func; if it is, then apply args if not (== [])
-- | then if we have args for a func: check if we chain (we can now assume the return-ed is an Object)
-- | DoChain --> pass return statement to chain statement
-- | Only ns@[Name] ~~ Property Grab from (Return x) --> \x -> evalRefObj ns x
-- | [Name] <+> FnCall ~~ Property Grab from (Return x) --> \x -> if isFn then evalFunc x args
-- | Except since this may infinitely repeat, call evalRef which will call evalFunc