~andyc/oil

5a2145f2b0148f603b923f596fc6d792a23c4abd — Andy Chu a month ago 28d0f7f
[oil-language] Restore dynamic check for var and const

- [spec/oil-assign] Fix assertion
2 files changed, 41 insertions(+), 1 deletions(-)

M core/state.py
M spec/oil-assign.test.sh
M core/state.py => core/state.py +13 -0
@@ 1276,6 1276,16 @@ class Mem(object):
    definition and mutation will help translate the Oil subset of OSH to static
    languages.
    """
    if cell is not None and keyword_id in (Id.KW_Var, Id.KW_Const):
      # This dynamic check is for 'local' before 'var', or 'readonly before
      # 'const', etc.
      #
      # Another option: REMOVE assignment builtins from 'proc'.  You can only
      # use keywords.

      # TODO: location
      e_die('%r has already been declared', name)

    # TODO: Also do this at parse time.  We have some name resolution in
    # ctx_Declarations.
    if cell is None and keyword_id in (Id.KW_Set, Id.KW_SetLocal,


@@ 1372,6 1382,9 @@ class Mem(object):
            cell.nameref = False

          if val is not None:  # e.g. declare -rx existing
            # TODO: Maybe DON'T enforce this for 'const', so we can have const
            # in a loop.  It's checked statically.  But that would change
            # 'readonly x=1; const x=2'.  Disallow assign builtins?
            if cell.readonly:
              # TODO: error context
              e_die("Can't assign to readonly value %r", lval.name)

M spec/oil-assign.test.sh => spec/oil-assign.test.sh +28 -1
@@ 60,7 60,7 @@ x = 'foo'
echo x=$x
const x = 'bar'
echo x=$x
## status: 1
## status: 2
## STDOUT:
x=foo
## END


@@ 257,6 257,31 @@ var x = "redeclaration is an error"
x=local
## END

#### mixing assignment builtins and Oil assignment
shopt -s oil:all

proc local-var {
  local x=1
  var x = 2
  echo x=$x
}

proc readonly-const {
  readonly x=1
  x = 2
  echo x=$x
}

run --assign-status :st eval 'local-var'
echo status=$st
run --assign-status :st eval 'readonly-const' || true
echo status=$st

## STDOUT:
status=1
status=1
## END

#### setvar modified local or global scope
modify_with_shell_assignment() {
  f=shell


@@ 334,3 359,5 @@ setvar L[0] = L
## END