Last active
February 26, 2020 02:10
-
-
Save mmisamore/5bddbe4658dbdca72292530b7c6e69d8 to your computer and use it in GitHub Desktop.
A simple record generation macro in swi-prolog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:- use_module(library(clpfd)). | |
% True if TypeFieldFunctor is the functor built from TypeName and FieldName atoms | |
% with an underscore between | |
type_field_functor(TypeName, FieldName, TypeFieldFunctor) :- | |
atom_chars(TypeName, TypeChars), | |
atom_chars(FieldName, FieldChars), | |
append(TypeChars, ['_'], TypeUnderscore), | |
append(TypeUnderscore, FieldChars, TypeFieldFunctorChars), | |
atom_chars(TypeFieldFunctor, TypeFieldFunctorChars). | |
% True if Term relates record TypeName of TypeArity to one of its fields named | |
% FieldName appearing at index FieldPos | |
field_term(Term, TypeName, TypeArity, FieldName, FieldPos) :- | |
type_field_functor(TypeName, FieldName, Functor), | |
Term =.. [Functor, Arg1, Arg2], | |
functor(Arg1, TypeName, TypeArity), % Arg1 is the record | |
arg(FieldPos, Arg1, Arg2). % Arg2 is the FieldPos argument of Arg1 | |
% True when Terms is a list of terms describing access to each FieldName of a record | |
% with name TypeName | |
field_terms(_, [], [], TypeArity, TypeArity). | |
field_terms(TypeName, [FieldName|FieldNames], [Term|Terms], I, TypeArity) :- | |
Pos #= I + 1, | |
field_term(Term, TypeName, TypeArity, FieldName, Pos), | |
field_terms(TypeName, FieldNames, Terms, Pos, TypeArity). | |
field_terms(TypeName, FieldNames, Terms) :- | |
length(FieldNames, TypeArity), | |
field_terms(TypeName, FieldNames, Terms, 0, TypeArity). | |
% Hook the record generation macro | |
term_expansion(define_record(TypeName, FieldNames), Terms) :- | |
field_terms(TypeName, FieldNames, Terms). | |
% Try the macro | |
define_record(player, [name, exp, hp, level]). | |
define_record(monster, [name, exp, mp]). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment