code: def p_substr_assignment(p):
      
      if p[3] is None or p[5] is None:
          return  # There were errors
  
      p[0] = None
      entry = SYMBOL_TABLE.access_call(p[2], p.lineno(2))
      if entry is None:
          return
  
      if entry.class_ == CLASS.unknown:
          entry.class_ = CLASS.var
  
      assert entry.class_ == CLASS.var and entry.type_ == TYPE.string
  
      if p[5].type_ != TYPE.string:
          api.errmsg.syntax_error_expected_string(p.lineno(4), p[5].type_)
  
      if len(p[3]) > 1:
          syntax_error(p.lineno(2), "Accessing string with too many indexes. Expected only one.")
          return
  
      if len(p[3]) == 1:
          substr = (
              make_typecast(_TYPE(gl.STR_INDEX_TYPE), p[3][0].value, p.lineno(2)),
              make_typecast(_TYPE(gl.STR_INDEX_TYPE), p[3][0].value, p.lineno(2)))
      else:
          substr = (make_typecast(_TYPE(gl.STR_INDEX_TYPE),
                                  make_number(gl.MIN_STRSLICE_IDX,
                                              lineno=p.lineno(2)),
                                  p.lineno(2)),
                    make_typecast(_TYPE(gl.STR_INDEX_TYPE),
                                  make_number(gl.MAX_STRSLICE_IDX,
                                              lineno=p.lineno(2)),
                                  p.lineno(2)))
  
      lineno = p.lineno(2)
      base = make_number(OPTIONS.string_base.value, lineno, _TYPE(gl.STR_INDEX_TYPE))
      p[0] = make_sentence('LETSUBSTR', entry,
                           make_binary(lineno, 'MINUS', substr[0], base, func=lambda x, y: x - y),
                           make_binary(lineno, 'MINUS', substr[1], base, func=lambda x, y: x - y),
                           p[5])
docs: statement : LET ID arg_list EQ expr