Writing oslib defs
Use when writing, reading, or reviewing OSLib Def interface description files, or when generating C headers, ObjAsm veneers, assembler/C SWI headers, SrcEdit help, or StrongHelp content from them with riscos-defmod.From its SKILL.md
npx -y skills add gerph/riscos-agent-skills --skill writing-oslib-defsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
4.7 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Writing OSLib Def files
A Def file is a compact, declarative description of an OSLib-style RISC OS
interface: module metadata, types, constants, and SWI signatures. One
reviewed Def file is processed by riscos-defmod to derive C headers, ObjAsm
veneers, assembler headers, SrcEdit help, and StrongHelp content, so the Def
file is the source of truth and the generated files are build artefacts.
Read only the reference files needed for the task:
- Full grammar (types, structs, SWI entry/exit conditions, literals):
references/grammar.md riscos-defmodcommand-line flags and output-format selectors:references/command-line.md
The one rule that will trip you up
The semicolon between declarations is a separator, not a terminator. A
trailing semicolon after the last top-level declaration in the file is a
syntax error reported at end of file, even though every other pair of
declarations must be separated by one. Verified directly against the real
defmod binary and against oslibsrc/Core/def/portable, a genuine
production Def file, which itself ends on a bare closing parenthesis with no
trailing semicolon.
TITLE Example "Example OSLib interface";
AUTHOR "Example Author";
NEEDS os;
CONST ExampleReason = .int: 1 "Primary reason code";
TYPE ExampleBlock = .struct (.int: value, .bool: enabled);
SWI Example_DoThing = (NUMBER &54321 "DoThing",
ENTRY (R0 -> ExampleBlock: block,
R1 # ExampleReason),
EXIT (R0! = .int: result, R1 ?))
Note there is no semicolon after the closing )) of the SWI declaration,
because it is the last declaration in the file. If another declaration
followed it, that SWI declaration would need a trailing semicolon to
separate it from the next one.
Minimal worked example
This is the smallest realistic file: metadata, one constant, and one SWI.
TITLE Example;
AUTHOR "Test Author";
NEEDS OS;
CONST
ReasonCode = .Int: 5 "Reason code for the SWI";
SWI
Example_Call =
( NUMBER &12345 "Example call",
ENTRY
( R0 = .Int: value,
R1 # ReasonCode
),
EXIT
( R0! = .Int: result
) )
Type and keyword names are matched case-insensitively by the lexer, so
.Int/.int, TITLE/title, and similar pairs are equivalent; pick one
style and stay consistent within a file.
Running riscos-defmod
riscos-defmod reads the Def file from standard input; most output forms
write to standard output, so redirect them yourself:
mkdir -p h s
riscos-defmod -h < InterfaceDef > h/interface # C header
riscos-defmod -hdr < InterfaceDef > h/interface_asm # ObjAsm header
riscos-defmod -s -byte_wide bytewide.txt < InterfaceDef > s/interface # ObjAsm veneers
Directory-producing modes (-l, -cstrong) take -o <dir> and create that
directory themselves; everything else relies on the shell redirection, so the
destination directory for those must already exist:
riscos-defmod -l -o LibraryOut -26bit -32bit < InterfaceDef
See references/command-line.md for the full flag list, including which
historical flags (-p for Pascal, -asmstrong) are accepted by the parser
but do not actually produce output.
Workflow
- Write or edit the
.Defsource describing the interface (types, constants, SWI signatures). - Generate the header(s) and veneer(s) you need with
riscos-defmod. - Build the generated
.s/.oveneer alongside your C source in the normal way; seeusing-makefilesfor wiring this into a project's build. - Keep the Def file under source control as the reviewed artefact; treat generated output as disposable and regenerate it on each build.
Style guidelines
- Keep one
Deffile per logical interface (module or shared header), named to match itsTITLE. - Use
NEEDSto declare cross-interface dependencies explicitly rather than relying on include order in generated headers. - Prefer named
TYPEdeclarations over inline.struct/.unionexpressions when a structure is used by more than one SWI, so the generated header gives it a stable name. - Use the starred-description form (
NUMBER &12345 "description"or a bare*) on SWI numbers and constant reason codes you want exposed as named manifest constants in generated headers; omit it for values that are implementation detail only. - Do not hand-edit generated headers, veneers, or help output — re-run
riscos-defmodafter editing the Def file instead.
What ships with it: 3 files
8.2 KB alongside SKILL.md
agents/
- openai.yaml268 B
references/
- command-line.md2.2 KB
- grammar.md5.8 KB