code: def make_call(id_, lineno, args):
      
      assert isinstance(args, symbols.ARGLIST)
  
      entry = SYMBOL_TABLE.access_call(id_, lineno)
      if entry is None:
          return None
  
      if entry.class_ is CLASS.unknown and entry.type_ == TYPE.string and len(args) == 1 and is_numeric(args[0]):
          entry.class_ = CLASS.var  # A scalar variable. e.g a$(expr)
  
      if entry.class_ == CLASS.array:  # An already declared array
          arr = symbols.ARRAYLOAD.make_node(id_, args, lineno)
          if arr is None:
              return None
  
          if arr.offset is not None:
              offset = make_typecast(TYPE.uinteger,
                                     make_number(arr.offset, lineno=lineno),
                                     lineno)
              arr.appendChild(offset)
          return arr
  
      if entry.class_ == CLASS.var:  # An already declared/used string var
          if len(args) > 1:
              api.errmsg.syntax_error_not_array_nor_func(lineno, id_)
              return None
  
          entry = SYMBOL_TABLE.access_var(id_, lineno)
          if entry is None:
              return None
  
          if len(args) == 1:
              return symbols.STRSLICE.make_node(lineno, entry, args[0].value, args[0].value)
  
          entry.accessed = True
          return entry
  
      return make_func_call(id_, lineno, args)
docs: This will return an AST node for a function call/array access.
  
      A "call" is just an ID followed by a list of arguments.
      E.g. a(4)
      - a(4) can be a function call if 'a' is a function
      - a(4) can be a string slice if a is a string variable: a$(4)
      - a(4) can be an access to an array if a is an array
  
      This function will inspect the id_. If it is undeclared then
      id_ will be taken as a forwarded function.