Skip to content

Commit

Permalink
[oil-language] Implement 'setvar x += 1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Chu committed Jul 11, 2019
1 parent 854bda4 commit 0ceeabc
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
26 changes: 15 additions & 11 deletions oil_lang/expr_eval.py
Expand Up @@ -26,6 +26,20 @@ def __init__(self, mem, errfmt):
self.mem = mem
self.errfmt = errfmt

def ToAny(self, val):
"""Convert to a Python object so we can calculate on it natively."""
if val.tag == value_e.Undef:
# TODO: e_die with token
raise NameError('undefined')
if val.tag == value_e.Str:
return val.s
if val.tag == value_e.StrArray:
return val.strs # node: has None
if val.tag == value_e.AssocArray:
return val.d
if val.tag == value_e.Obj:
return val.obj

def EvalLHS(self, node):
if 0:
print('EvalLHS()')
Expand Down Expand Up @@ -68,17 +82,7 @@ def EvalRHS(self, node):

if node.tag == expr_e.Var:
val = self.mem.GetVar(node.name.val)
if val.tag == value_e.Undef:
# TODO: e_die with token
raise NameError('undefined')
if val.tag == value_e.Str:
return val.s
if val.tag == value_e.StrArray:
return val.strs # node: has None
if val.tag == value_e.AssocArray:
return val.d
if val.tag == value_e.Obj:
return val.obj
return self.ToAny(val)

if node.tag == expr_e.DoubleQuoted:
s = ''.join(self.EvalWordPart(part) for part in node.parts)
Expand Down
20 changes: 18 additions & 2 deletions oil_lang/testdata/hello.osh
Expand Up @@ -6,6 +6,11 @@ var x = 1 + 2*3

echo "x: $x"

# NOTE: we will take over 'set'
setvar x += 1

echo "x: $x"

var mylist = [1, 2, 3]

var y = mylist[1] * 10
Expand All @@ -31,7 +36,18 @@ echo "str3 = $str3"



#var f1 = 1.23
#var f2 = 3.45



# TODO:
# - Mutate variables
# - Demo dicts
# - lexing
# - single-quoted strings
# - floats
# - parsing
# - dicts
# - comments at end of line
# - eval
# - Mutate variables with 'setvar'

21 changes: 16 additions & 5 deletions osh/cmd_exec.py
Expand Up @@ -768,13 +768,24 @@ def _Dispatch(self, node, fork_external):
# TODO: maybe pick out LHS and RHS here.
# And then use mem and everything.

assert node.op.id == Id.Arith_Equal, node.op

lval = self.expr_ev.EvalLHS(node.lhs)
py_val = self.expr_ev.EvalRHS(node.rhs)
val = value.Obj(py_val)
flags = ()
self.mem.SetVar(lval, val, flags, scope_e.LocalOnly)

if node.op.id == Id.Arith_Equal:
val = value.Obj(py_val)
flags = ()
self.mem.SetVar(lval, val, flags, scope_e.LocalOnly)

elif node.op.id == Id.Arith_PlusEqual:
old_val = self.mem.GetVar(lval.name)
old_py_val = self.expr_ev.ToAny(old_val)

val = value.Obj(old_py_val + py_val)
flags = ()
self.mem.SetVar(lval, val, flags, scope_e.LocalOnly)

else:
raise NotImplementedError(node.op)

status = 0 # TODO: what should status be?

Expand Down

0 comments on commit 0ceeabc

Please sign in to comment.