Line number (and file name) of fact read

Hello,

I am using term expansion to create a Domain Specific Language (DSL).

For example, keyword(X) gets expanded to dsl(keyword(X)).

A failure driven loop then reads each keyword in sequence:

process :-
    dsl(X),
    process(X),
    fail.

process.

Is there a way to determine the line number in the file in which the fact dsl(X) appears on the file?

I’d like to use is to report syntax or semantic errors …

E.g. what I want to write out after reading dsl(keyword(arg)) on line 5 in file trial.pl

Warning': keyword(arg) in line 5 of file: trial.pl - expected arg2 instead. 

Can this be done?

Thanks,

Dan

1 Like

Does this help?

?- read_term(Z, [subterm_positions(X), term_position(Y)]).
|: foo(a,[1,2,3]).

Z = foo(a, [1, 2, 3]),
X = term_position(666, 680, 666, 669, [670-671, list_position(672, 679, [673-674, 675-676, 677-678], none)]),
Y = '$stream_position'(666, 30, 0, 666).

?- [user].
|: foo(a, [1,2,3]).
|: ^D% user://1 compiled 0.00 sec, 1 clauses
true.

?- predicate_property(foo(_,_), Property), writeln(Property), fail; true.
interpreted
visible
static
file(user://1)
line_count(37)
number_of_clauses(1)
number_of_rules(0)
last_modified_generation(23889)
defined
true.

Thank you.

So, this means I would do something like that:

process :-
    read_term(dsl(X), term_position(Y)),
    writeln(Y),
    process(X),
    fail.

process.

See https://www.swi-prolog.org/pldoc/doc_for?object=prolog_load_context/2

See clause_property/2. As long as the clause was produced with term_expansion/2 in a normal load this will give the file and line for each clause. See also clause_info/5, although that may require some additional rules if the clause has been transformed.

2 Likes