Permalink
Browse files

[osh2oil] Clean up translation of assignments.

- Add more failing tests for complex assignments
- Add test for C literals
  • Loading branch information...
Andy Chu
Andy Chu committed Aug 26, 2018
1 parent 5be087f commit 56834959f0f3cb5909a249a33dc86d80a3305ef1
Showing with 66 additions and 15 deletions.
  1. +58 −1 test/osh2oil.sh
  2. +8 −14 tools/osh2oil.py
View
@@ -483,9 +483,39 @@ f() { foo=bar spam=${var:-default}; }
OSH
proc f { setglobal foo = 'bar', spam = $(var or 'default'); }
OIL
}
assign-with-flags() {
osh0-oil3 << 'OSH' 3<< 'OIL'
declare -r foo=bar
OSH
const foo = 'bar'
OIL
osh0-oil3 << 'OSH' 3<< 'OIL'
declare -x foo=bar
OSH
export var foo = 'bar'
OIL
osh0-oil3 << 'OSH' 3<< 'OIL'
declare -rx foo
declare -r -x foo
OSH
export const foo
export const foo
OIL
osh0-oil3 << 'OSH' 3<< 'OIL'
f() {
local -r foo=bar
}
OSH
proc f {
const foo = 'bar'
}
OIL
}
array-literal() {
osh0-oil3 << 'OSH' 3<< 'OIL'
@@ -966,6 +996,25 @@ echo \
OIL
}
# Hm I still don't have a syntax for this. I don't like $'' because it's
# confusing with a var. Use some other punctuation charater like %?
# @'' and @"" ? &'' &"" ?
#
# Or get rid of word joining? 'foo'"'" becomes c'foo\''
# Glob/*.py/
# C'foo'
# List [1, 2, 'hi'] # JSON
#
# Yeah maybe capital C is better.
c-literal() {
osh0-oil3 << 'OSH' 3<< 'OIL'
echo $'\tline\n'
OSH
echo c'\tline\n'
OIL
}
words() {
# I probably should drive this with specific cases, rather than making it
# super general. Most scripts don't use WordPart juxtaposition.
@@ -986,6 +1035,14 @@ echo "$HOME/name with spaces"
OIL
}
word-joining() {
osh0-oil3 << 'OSH' 3<< 'OIL'
echo 'foo'"'"
OSH
echo c'foo\''
OIL
}
time-block() {
osh0-oil3 << 'OSH' 3<< 'OIL'
time ls
View
@@ -341,10 +341,8 @@ def DoAssignment(self, node, at_top_level, local_symbols):
# Oil keywords:
# - global : scope qualifier
# - var, const : mutability
# - setconst, export : state mutation
#
# Operators:
# = and :=
# - export : state mutation
# - setconst -- make a variable mutable. or maybe freeze var?
#
# NOTE: Bash also has "unset". Does anyone use it?
# You can use "delete" like Python I guess. It's not the opposite of
@@ -357,9 +355,6 @@ def DoAssignment(self, node, at_top_level, local_symbols):
# files are in the program.
defined_locally = False # is it a local variable in this function?
# can't tell if global
# We can change it from = to := or ::= (in pedantic mode)
new_assign_op_e = None
if node.keyword == Id.Assign_Local:
# Assume that 'local' it's a declaration. In osh, it's an error if
# locals are redefined. In bash, it's OK to do 'local f=1; local f=2'.
@@ -402,8 +397,9 @@ def DoAssignment(self, node, at_top_level, local_symbols):
self.f.write('set ')
#self.f.write('[local mutated]')
else:
# we're in a function, but it's not defined locally.
self.f.write('setglobal ') # assume mutation of local
# We're in a function, but it's not defined locally, so we must be
# mutatting a global.
self.f.write('setglobal ')
elif node.keyword == Id.Assign_Readonly:
# Explicit const. Assume it can't be redefined.
@@ -421,6 +417,8 @@ def DoAssignment(self, node, at_top_level, local_symbols):
self.cursor.SkipUntil(keyword_spid + 1)
self.f.write('const')
elif defined_locally:
# TODO: Actually we might want 'freeze here. In bash, you can make a
# variable readonly after its defined.
raise RuntimeError("Constant redefined locally")
else:
# Same as global level
@@ -451,11 +449,7 @@ def DoAssignment(self, node, at_top_level, local_symbols):
# Replace name. I guess it's Lit_Chars.
self.f.write(pair.lhs.name)
op = new_assign_op_e if new_assign_op_e else '='
self.f.write(' %s ' % op)
# foo=bar -> foo = 'bar'
#print('RHS', pair.rhs, file=sys.stderr)
self.f.write(' = ')
# TODO: This should be translated from EmptyWord.
if pair.rhs is None:

0 comments on commit 5683495

Please sign in to comment.