## planfile.api
#
# Compiled by:
#
src/lib/std/standard.libstipulate
package pfs = patchfiles; # patchfiles is from
src/lib/make-library-glue/patchfiles.pkg package sm = string_map; # string_map is from
src/lib/src/string-map.pkgherein
# This api is implemented in:
#
#
src/lib/make-library-glue/planfile.pkg #
api Planfile
{
# Field is a contiguous sequence of lines
# all with the same linetype field:
#
# foo: this
# foo: that
#
# Most fields will be single-line, but this format
# supports conveniently including blocks of code,
# such as complete function definitions.
#
Field = { fieldname: String, # Label appearing before the colon, trimmed of whitespace.
lines: List(String), # Line(s) for this field, stripped of initial label and colon.
filename: String, # Name of file from which field was read.
line_1: Int, # First line number in file for field.
line_n: Int, # Last line number in file for field.
used: Ref(Bool)
};
Fields = sm::Map( Field ); # Stored indexed by field name.
Paragraph
=
{ fields: Fields, # Stored indexed by field name.
filename: String, # Name of file from which paragraph was read.
line_1: Int, # First line number in file for paragraph.
line_n: Int # Last line number in file for paragraph.
};
Do_Fn(X) # Does all required work to implement the paragraph type.
=
{ patchfiles: pfs::Patchfiles, # Patchfiles being modified.
paragraph: Paragraph, # Fields providing the call-specific information driving the modification.
x: X # Whatever random background information the client code needs passed in.
}
-> pfs::Patchfiles; # Updated patchfiles.
Paragraph_Plus_Do_Fn(X)
=
{ paragraph: Paragraph,
do: Do_Fn(X)
};
Plan(X) = List( Paragraph_Plus_Do_Fn(X) ); # Synonym for readability.
Field_Trait
#
= OPTIONAL
| DO_NOT_TRIM_WHITESPACE
| ALLOW_MULTIPLE_LINES
;
Field_Traits = { optional: Bool, # TRUE if this field may be omitted from paragraph.
trim_whitespace: Bool, # TRUE if leading and trailing whitespace should be trimmed from lines for this fieldtype.
allow_multiple_lines: Bool
};
Field_Definition
=
{ fieldname: String,
traits: List( Field_Trait )
};
Paragraph_Definition(X)
=
{ name: String, # The 'do:' line value.
do: Do_Fn(X), # Does all required work to implement the paragraph type.
#
fields: List( Field_Definition )
};
Digested_Paragraph_Definition(X)
=
{ name: String,
do: Do_Fn(X),
fields: sm::Map( Field_Traits )
};
Digested_Paragraph_Definitions(X)
=
sm::Map( Digested_Paragraph_Definition(X) ); # Stored indexed by name.
digested_paragraph_definition_to_string # Generate human-readable form for debugging and such.
:
Digested_Paragraph_Definition(X)
->
String
;
digest_paragraph_definitions
:
Digested_Paragraph_Definitions(X) # Previously digested definitions. sm::empty will do.
-> String # Name of file holding paragraph definitions, for diagnostics.
-> List(Paragraph_Definition(X)) # New paragraph definitions to digest.
-> Digested_Paragraph_Definitions(X)
;
# Digest caller-provided paragraph definitions into internal form.
# This mainly involves sanity checking:
#
# o Each fieldname should be lexically sane. Currently this means matching [A-Za-z0-9_\-+]+
# o Each 'do:' paragraph type should be defined at most once.
# o Within a paragraph definition, each field should be defined at most once.
read_planfile:
Digested_Paragraph_Definitions(X) # Supported paragraph types. Used to validate input paragraphs.
-> String # The filename to read.
-> Plan(X) # The validated paragraphs from the planfiles.
;
read_planfiles:
Digested_Paragraph_Definitions(X) # Supported paragraph types. Used to validate input paragraphs.
-> List( String ) # The filenames to read.
-> Plan(X) # The validated paragraphs from the planfiles.
;
map_patchfiles_per_plan:
X
-> pfs::Patchfiles
-> Plan(X)
-> pfs::Patchfiles
;
};
end;