Skip to content

Commit

Permalink
[oil-language] Able to use the + operator on lists and strings too.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Chu committed Jul 11, 2019
1 parent b4ddfbd commit 854bda4
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
6 changes: 6 additions & 0 deletions asdl/gen_python.py
Expand Up @@ -51,6 +51,9 @@ def _CodeSnippet(self, method_name, var_name, desc):
elif isinstance(desc, meta.StrType):
code_str = 'PrettyLeaf(%s, Color_StringConst)' % var_name

elif isinstance(desc, meta.AnyType):
code_str = 'PrettyLeaf(str(%s), Color_OtherConst)' % var_name

elif isinstance(desc, meta.DictType):
# Dicts are used for AssocArray in osh/runtime.asdl
# I think it makes sense to treat it as a leaf.
Expand Down Expand Up @@ -145,6 +148,9 @@ def _GenClass(self, desc, class_name, super_name, depth, tag_num=None):
elif isinstance(field_desc, meta.StrType):
type_str = 'str'

elif isinstance(field_desc, meta.AnyType):
type_str = 'Any'

elif isinstance(field_desc, meta.UserType):
type_str = field_desc.type_name

Expand Down
7 changes: 6 additions & 1 deletion asdl/meta.py
Expand Up @@ -15,6 +15,11 @@ class _RuntimeType(object):
pass


class AnyType(_RuntimeType):
def __repr__(self):
return '<Any>'


class StrType(_RuntimeType):
def __repr__(self):
return '<Str>'
Expand Down Expand Up @@ -112,6 +117,6 @@ def LookupFieldType(self, field_name):

# TODO: This is a hack for the Oil expression evaluator. We're not doing
# any dynamic or static checking now.
'any': StrType(),
'any': AnyType(),
}

35 changes: 30 additions & 5 deletions oil_lang/expr_eval.py
Expand Up @@ -4,14 +4,12 @@
"""
from __future__ import print_function

import sys

from _devbuild.gen.id_kind_asdl import Id
from _devbuild.gen.syntax_asdl import (
expr_e,
expr_e, oil_word_part_e
)
from _devbuild.gen.runtime_asdl import (
lvalue, value
lvalue, value_e
)


Expand Down Expand Up @@ -42,10 +40,23 @@ def EvalLHS(self, node):

raise NotImplementedError(node.__class__.__name__)

def EvalWordPart(self, part):
"""
TODO: We might not want oil_word_part_e? Just use OSH word_part?
"""
if part.tag == oil_word_part_e.Literal:
return part.token.val

raise NotImplementedError(part.__class__.__name__)

def EvalRHS(self, node):
"""
This is a naive PyObject evaluator! It uses the type dispatch of the host
Python interpreter.
Returns:
A Python object of ANY type. Should be wrapped in value.Obj() for
storing in Mem.
"""
if 0:
print('EvalRHS()')
Expand All @@ -57,7 +68,21 @@ def EvalRHS(self, node):

if node.tag == expr_e.Var:
val = self.mem.GetVar(node.name.val)
return val.obj
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

if node.tag == expr_e.DoubleQuoted:
s = ''.join(self.EvalWordPart(part) for part in node.parts)
return s

if node.tag == expr_e.Binary:
left = self.EvalRHS(node.left)
Expand Down
18 changes: 18 additions & 0 deletions oil_lang/testdata/hello.osh
Expand Up @@ -12,6 +12,24 @@ var y = mylist[1] * 10

echo "y: $y"

var list2 = mylist + [4, 5]

# This prints [1,2,3,4,5], not sure if we want a different representation
echo $list2

# This is a more explicit representation.
repr list2

str1='shell string' # traditinoal shell-style assignment

# Oil assignment
var str2 = "Oil string"

var str3 = str1 + str2

echo "str3 = $str3"



# TODO:
# - Mutate variables
Expand Down

0 comments on commit 854bda4

Please sign in to comment.