lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.5k stars 157 forks source link

FunctionCall: spec doesn't match actual #1508

Open rebcabin opened 1 year ago

rebcabin commented 1 year ago

The spec in ASR.asdl for FunctionCall states:

    | FunctionCall(symbol name, symbol? original_name, call_arg* args,
            ttype type, expr? value, expr? dt)

An example generated from tests/expr7.py does not match the spec. There is an extra element and symbols should be identifiers' (as with Issue #1492; they're notsymbol`s from the point of view of my semi-automated Clojure spec processors), with my guesses for the actual meanings and with commentary about type mis-matches:

(FunctionCall
 1  ; <~~~~~~~ probably a stid (symbol-table-id) as with SubroutineCall
 test_pow_1  ; <~~~~~~~ should have type "identifier," not "symbol"
 ()  ; <~~~~~~~ probably "original_name," should be "identifier?," not "symbol?"
 [((IntegerConstant 1 (Integer 4 [])))  ; <~~~~~~~ call_arg* args; OK
  ((IntegerConstant 2 (Integer 4 [])))]
 (Integer 4 [])  ; <~~~~~~~ ttype; OK
 ()  ; <~~~~~~~ expr? value; OK
 ())  ; <~~~~~~~ expr? dt; OK
rebcabin commented 1 year ago

In the light of a new example (below), I've now deduced that name should be a SymbolRef, (see Issue #1492), i.e.,

SymbolRef(symtab_id id, identifier name)

In the example above, 1 and test_pow_1 are a naked (interpolated) pair. original_name is an empty list because a non-existent naked pair can't be expressed (it would be invisible. original_name should also be a SymbolRef. The new example below makes this clear.

        (FunctionCall
         2  ; <~~~~~~~ this is a stid (symbol-table-id)
         pow/__lpython_overloaded_0__pow  ; <~~~~~~~ this is an identifier
         ; the pair above should be SymbolRef(1, pow/__lpython_overloaded_o__pow)
         2  ; <~~~~~~~~ this is a stid
         pow  ; <~~~~~~~ this is an identifier
         ; the pair above should be SymbolRef(2, pow)
         [((IntegerConstant 2 (Integer 4 [])))
          ((IntegerConstant 2 (Integer 4 [])))]
         (Real 8 [])
         (RealConstant 4.0 (Real 8 []))
         ())

Until this is fixed, I must write non-robust code to scan for such interpolated pairs and possible empty lists standing for empty interpolated lists.

rebcabin commented 1 year ago

I think we need a new symconst, NullSymbolRef, to stand in for () in the slot for original_name, to make the processing of this spec more robust.

certik commented 1 year ago

The symbol issue is due to https://github.com/lcompilers/lpython/issues/1510.