diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 09:18:23 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 09:18:23 +0000 |
| commit | 9467ae311ddc0ce8b4c329f3dbcec88fb279719d (patch) | |
| tree | 6102b28ca01d88c96bab5d13a4f0dcb547649d2f /doc | |
| parent | 64aa538142148faf06b9a3c71907eacee04cd49d (diff) | |
docs: multi-file builds
Document INCLUDE visibility, primitive GLOBAL variables and MAIN entry rules,
and highlight the new keywords in the editor grammar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/cpsc.1.md | 22 | ||||
| -rw-r--r-- | doc/language/cpsc-language-overview.7.md | 6 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-function.7.md | 2 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-global.7.md | 45 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-include.7.md | 42 |
5 files changed, 110 insertions, 7 deletions
diff --git a/doc/cpsc.1.md b/doc/cpsc.1.md index 92f73b5..2bb1f1c 100644 --- a/doc/cpsc.1.md +++ b/doc/cpsc.1.md @@ -6,15 +6,19 @@ cpsc - compile and run CIE pseudocode # SYNOPSIS -**cpsc** [**-r**] [**-S**] [**-o** *output*] *source* +**cpsc** [**-r**] [**-S**] [**-o** *output*] *source* [*source* ...] **cpsc** **-h** # DESCRIPTION -Compile one pseudocode source file to a native executable, or to textual LLVM IR with **-S**. Options may appear before or after the source path. Source input from stdin is not supported. +Compile one or more pseudocode source files to a native executable, or to textual LLVM IR with **-S**. Options may appear among the source paths. Source input from stdin is not supported. -Without **-o**, save beside the source file, replacing its extension with `.out` for an executable or `.ll` for IR. This naming also applies on Windows. With **-r** alone, run without saving a file. +Without **-o**, save beside the entry source file, replacing its extension with `.out` for an executable or `.ll` for IR. This naming also applies on Windows. With **-r** alone, run without saving a file. + +Each input is a compilation unit. Use top-level `INCLUDE "lib.cps"` to import another input's exported definitions, including its transitive imports. Paths are relative to the including source; every included file must also appear on the command line. Repeated includes and include cycles are harmless. Giving the same input twice, including symbolic or hard links, is an error. Duplicate definitions across files are errors even if the files do not include each other. + +Exactly one file may contain top-level executable statements (including top-level DECLARE). Alternatively, define a parameterless `FUNCTION MAIN RETURNS INTEGER` in one file and have no top-level executable statements anywhere. Builds containing only definitions and no MAIN fail with `error: no main program`. GLOBAL blocks declare shared primitive variables. INCLUDE, GLOBAL and MAIN entry points are compiler extensions beyond the Cambridge guide. # OPTIONS @@ -25,7 +29,7 @@ Without **-o**, save beside the source file, replacing its extension with `.out` : Save to the specified path. Without **-S**, save a native executable; with **-S**, save LLVM IR. Use the path exactly as given; its extension does not select the output format. May be specified only once. With **-r**, keep this file even if execution fails. **-S** -: Save textual LLVM IR instead of a native executable. Without **-o**, use the source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program. +: Save textual LLVM IR instead of a native executable. Without **-o**, use the entry source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program. **-r** : Run the compiled program with the runner selected at build time (see EXECUTION MODES). Save output first when **-S** or **-o** is also present; otherwise do not save a file. The program inherits stdin, stdout and stderr; `INPUT` can read terminal or piped input. @@ -88,6 +92,12 @@ cpsc test.cps -o test.out ./test.out ``` +Compile a program whose `me.cps` contains `INCLUDE "lib.cps"`: + +```sh +cpsc me.cps lib.cps -r +``` + # EXIT STATUS **0** @@ -96,13 +106,13 @@ cpsc test.cps -o test.out **1** : An argument, file, compilation or execution-engine error occurred, including missing input, when PATH mode cannot validate `lli` from LLVM 23 or NONE mode receives **-r**. -With **-r**, return the executed program's exit status. In PATH mode, failure to launch `lli` or a child-process crash returns 1. +With **-r**, return the executed program's exit status. MAIN's INTEGER result is truncated to 32 bits before returning to the operating system. In PATH mode, failure to launch `lli` or a child-process crash returns 1. An uncaught program exception returns 1 after printing `Unhandled exception. Program terminated.` to standard output. Runtime check failures print the source line and error reason to standard output before throwing and can be handled with TRY/CATCH/ENDTRY. # NOTES -Compiler diagnostics go to stderr. Failed source compilation does not write output; failed native linking does not replace an existing output file. Successful compilation overwrites an existing output file, but an output path that refers to the source file (including a symbolic or hard link) is rejected. +Compiler diagnostics go to stderr. With multiple input files, lexer, parser and code generation diagnostics include the source path after the line number. Failed source compilation does not write output; failed native linking does not replace an existing output file. Successful compilation overwrites an existing output file, but an output path that refers to any input source file (including a symbolic or hard link) is rejected. Missing input, including invoking `cpsc` without arguments, reports `cpsc: fatal error: no input files`. Ordinary lexical, syntax and semantic errors use `error:`; failures that prevent compilation, such as file I/O errors, use `fatal error:`. Compilation and argument failures end with one `compilation terminated.` line. Execution-stage failures do not print that line. diff --git a/doc/language/cpsc-language-overview.7.md b/doc/language/cpsc-language-overview.7.md index cb31d93..b03e0df 100644 --- a/doc/language/cpsc-language-overview.7.md +++ b/doc/language/cpsc-language-overview.7.md @@ -20,8 +20,12 @@ Declare variables before use. See DECLARE for built-in types and arrays, TYPE fo The compiler extensions TRY/CATCH/ENDTRY and THROW support anonymous exceptions with stack unwinding. Runtime check failures print the source line and error reason to standard output before throwing and can be caught. An uncaught exception also prints a generic termination message and returns status 1. There is no error object or what() support. +Multi-file builds use the compiler extensions INCLUDE and GLOBAL. Pass every source file on the command line and include the files whose definitions are needed. The entry file contains the sole top-level executable code, or a parameterless FUNCTION MAIN returning INTEGER; definitions alone do not form a runnable program. + # KEYWORDS +- [cpsc-keyword-include(7)](keyword/cpsc-keyword-include.7.md): import definitions from another compilation unit. +- [cpsc-keyword-global(7)](keyword/cpsc-keyword-global.7.md): declare shared primitive variables. - [cpsc-keyword-constant(7)](keyword/cpsc-keyword-constant.7.md): declare a named literal with block scope. - [cpsc-keyword-declare(7)](keyword/cpsc-keyword-declare.7.md): declare variables and arrays. - [cpsc-keyword-input(7)](keyword/cpsc-keyword-input.7.md): read a value from standard input. @@ -49,7 +53,7 @@ The compiler extensions TRY/CATCH/ENDTRY and THROW support anonymous exceptions - [cpsc-keyword-div(7)](keyword/cpsc-keyword-div.7.md): perform integer division. - [cpsc-keyword-mod(7)](keyword/cpsc-keyword-mod.7.md): find the integer division remainder. -Closing and auxiliary keywords are documented with their main constructs: THEN/ELSE/ENDIF with IF; OF/OTHERWISE/ENDCASE with CASE; CATCH/ENDTRY/THROW with TRY; ENDWHILE with WHILE; UNTIL with REPEAT; TO/STEP/NEXT with FOR; RETURN/RETURNS/BYVAL/BYREF and function/procedure closing keywords with FUNCTION/PROCEDURE; READ/WRITE/APPEND with OPENFILE; ARRAY/OF and INTEGER/REAL/BOOLEAN/CHAR/STRING with DECLARE; ENDTYPE with TYPE; PUBLIC/PRIVATE/ENDCLASS with CLASS. TRUE/FALSE are BOOLEAN literals. +Closing and auxiliary keywords are documented with their main constructs: THEN/ELSE/ENDIF with IF; OF/OTHERWISE/ENDCASE with CASE; CATCH/ENDTRY/THROW with TRY; ENDWHILE with WHILE; UNTIL with REPEAT; TO/STEP/NEXT with FOR; RETURN/RETURNS/BYVAL/BYREF and function/procedure closing keywords with FUNCTION/PROCEDURE; READ/WRITE/APPEND with OPENFILE; ARRAY/OF and INTEGER/REAL/BOOLEAN/CHAR/STRING with DECLARE; ENDGLOBAL with GLOBAL; ENDTYPE with TYPE; PUBLIC/PRIVATE/ENDCLASS with CLASS. TRUE/FALSE are BOOLEAN literals. # BUILT-IN FUNCTIONS diff --git a/doc/language/keyword/cpsc-keyword-function.7.md b/doc/language/keyword/cpsc-keyword-function.7.md index c20bb50..d734da3 100644 --- a/doc/language/keyword/cpsc-keyword-function.7.md +++ b/doc/language/keyword/cpsc-keyword-function.7.md @@ -23,6 +23,8 @@ Parameters use `name : type`, optionally prefixed by BYVAL. BYVAL is the default A FUNCTION inside CLASS defines a member function, called as `Object.Method(arguments)`. It follows the same parameter and return rules. Within a method, use `this.Method(arguments)` to call another method on the current object; see [cpsc-keyword-class(7)](cpsc-keyword-class.7.md). +As a compiler extension, a top-level `FUNCTION MAIN RETURNS INTEGER` with no parameters supplies the program entry point. MAIN is case insensitive and cannot coexist with top-level executable statements in any input file. Its INTEGER result, truncated to 32 bits, is returned as the process exit status. An uncaught exception prints the generic termination message and returns 1. A PROCEDURE MAIN or a MAIN with parameters or a non-INTEGER result is an error. The usual default INTEGER result type also applies when RETURNS is omitted. + # EXAMPLE ```text diff --git a/doc/language/keyword/cpsc-keyword-global.7.md b/doc/language/keyword/cpsc-keyword-global.7.md new file mode 100644 index 0000000..643e0bb --- /dev/null +++ b/doc/language/keyword/cpsc-keyword-global.7.md @@ -0,0 +1,45 @@ +% CPSC-KEYWORD-GLOBAL(7) + +# NAME + +cpsc-keyword-global, cpsc-keyword-endglobal - declare shared primitive variables + +# SYNOPSIS + +```text +GLOBAL + DECLARE name : type + name <- literal +ENDGLOBAL +``` + +# DESCRIPTION + +GLOBAL and ENDGLOBAL are compiler extensions. Any number of GLOBAL blocks may appear at top level. Their bodies allow only DECLARE of INTEGER, REAL, CHAR, STRING or BOOLEAN variables and literal assignments to declared global variables. Negative numeric literals are allowed. Arrays, records, classes, C aliases, constructor arguments, calls, NEW and computed expressions are unsupported. + +Global variables have program lifetime and shared writable storage. They are visible throughout their own source file and in files importing them with INCLUDE, including inside functions and methods. Local variables and parameters may shadow them. Initializers are constants established before entry; omitted initializers use zero, FALSE or null, with null STRING values read as empty strings. A STRING literal initializes a pointer to shared literal storage. + +A GLOBAL block does not count as top-level executable code. A build still requires top-level executable statements in exactly one file, or a parameterless FUNCTION MAIN returning INTEGER. + +# EXAMPLE + +```text +GLOBAL + DECLARE Counter : INTEGER + Counter <- 2 +ENDGLOBAL + +PROCEDURE Increment + Counter <- Counter + 1 +ENDPROCEDURE + +FUNCTION MAIN RETURNS INTEGER + CALL Increment() + OUTPUT Counter + RETURN 0 +ENDFUNCTION +``` + +# SEE ALSO + +[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-include(7)](cpsc-keyword-include.7.md), [cpsc-keyword-declare(7)](cpsc-keyword-declare.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). diff --git a/doc/language/keyword/cpsc-keyword-include.7.md b/doc/language/keyword/cpsc-keyword-include.7.md new file mode 100644 index 0000000..5600472 --- /dev/null +++ b/doc/language/keyword/cpsc-keyword-include.7.md @@ -0,0 +1,42 @@ +% CPSC-KEYWORD-INCLUDE(7) + +# NAME + +cpsc-keyword-include - import definitions from another source file + +# SYNOPSIS + +```text +INCLUDE "path.cps" +``` + +# DESCRIPTION + +INCLUDE is a compiler extension, allowed only at top level. Resolve the path relative to the including source's directory. The included file must also be given on the command line; symbolic and hard links identify the same file. + +Import functions, procedures, types (including enum values), classes and methods, top-level constants and GLOBAL variables. Imports are transitive. Repeated includes and cycles are harmless: INCLUDE imports symbols rather than copying statements. A file always sees its own definitions. Using an unimported definition produces the usual unknown or undefined name error. Definitions must be unique across all input files, even when they are not imported. + +Imported constants are visible from the start of the including unit. A unit's own constants retain their ordinary declaration-order visibility. Top-level DECLARE variables are entry-program locals and are not exported. Pass all inputs together; there is no separate object-file compilation mode. + +# EXAMPLE + +`me.cps`: + +```text +INCLUDE "lib.cps" +OUTPUT Add(1, 2) +``` + +`lib.cps`: + +```text +FUNCTION Add(a : INTEGER, b : INTEGER) RETURNS INTEGER + RETURN a + b +ENDFUNCTION +``` + +Run with `cpsc me.cps lib.cps -r` to print `3`. + +# SEE ALSO + +[cpsc(1)](../../cpsc.1.md), [cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-global(7)](cpsc-keyword-global.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). |
