aboutsummaryrefslogtreecommitdiff
path: root/doc/cpsc.1.md
blob: e0e92e035db386c9b25ab440cc14a1210b6b5aa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

% CPSC(1)

# NAME

cpsc - compile and run CIE pseudocode

# SYNOPSIS

**cpsc** [**-r**] [**-S**] [**-no-std**] [**-fdiagnostics-color**[=*when*]] [**-o** *output*] *source* [*source* ...]

**cpsc** **-h**

# DESCRIPTION

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 entry source file, replacing its extension with `.exe` on Windows or `.out` elsewhere for an executable, or `.ll` for IR. 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; distinct signatures, differing in parameters or return type, may share a name when every definition specifies OVERLOAD.

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.

The embedded standard library is loaded and linked automatically. Its std.cps imports string.cps, which defines the STRING class and ordinary string functions, and memory.cps, which provides MALLOC/REALLOC/FREE and the allocation runtime used by keyword NEW/DELETE. No extra files are needed for default compilation. With **-no-std**, supply any required library inputs explicitly; ordinary string literals require a visible STRING class, and keyword NEW/DELETE require memory.cps. A literal with an adjacent uppercase C suffix, such as `"hello"C`, has type C_STRING and does not require that class.

# OPTIONS

**-h**
:   Print only the documentation entry point: `man 1 cpsc` on Unix/macOS, or Start Menu > cpsc > cpsc Help on Windows. Return successfully without compiling, even when other arguments are present.

**-o** *output*
:   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 entry source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program. Manually linking saved IR that uses the standard library requires the matching string.o, memory.o and C++ runtime; native output and **-r** supply them automatically.

**-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.

**-no-std**
:   Disable automatic standard-library loading and linking. Explicit INCLUDE and INCLUDE_OBJ inputs still work.

**-fdiagnostics-color**[=*when*], **-fno-diagnostics-color**
:   Color compiler diagnostics like gcc: the `file:line:` or `cpsc:` prefix in bold, `error:` and `fatal error:` in bold red, `warning:` in bold magenta and `note:` in bold cyan. *when* is `auto` (the default), `always` or `never`; **-fdiagnostics-color** alone means `always` and **-fno-diagnostics-color** means `never`. The last such option wins. `auto` colors only when stderr is a terminal: on Unix/macOS `TERM` must also be set and not `dumb`; on Windows the console must accept ANSI escape sequences. Runtime diagnostics of the compiled program are never colored.

# NATIVE COMPILATION

Native compilation uses LLVM, the Clang driver and LLD embedded in `cpsc`. Required startup objects, runtime archives and system-library link inputs are embedded too and unpacked temporarily when linking. No external compiler, linker or development SDK is needed. Generate programs for the compiler's own operating system and CPU architecture; cross-compilation is not supported.

On Linux, both `cpsc` and generated executables statically link the C++ runtime and retain dynamic dependencies on glibc and its system libraries. They require a compatible system glibc; static linking does not remove that requirement. Windows links non-system runtimes statically and uses Windows system DLLs. macOS uses operating-system libraries, including the system C++ runtime.

# EXECUTION MODES

The executable has one of the following execution modes, selected when it was built. All modes can generate native executables and LLVM IR; the mode determines whether and how **-r** runs the program. Running uses the selected runner even when a native executable is also saved.

**PATH**
:   Run `lli` from LLVM 23 in PATH. With **-r**, check the selected executable's version before compilation or output writing; a missing executable, a different major version or a failed or unrecognized version check is a fatal error. Version detection has a five-second timeout. Without **-r**, no external tools are checked. Execution uses temporary `.ll` IR unless **-S** saves IR; temporary IR is deleted afterward, including on execution failure.

**EMBEDDED**
:   Run the statically linked LLVM engine inside `cpsc`, without looking for `lli` in PATH. Execute the module in memory. Users do not need LLVM or `lli` installed; the executable may still depend on the operating system's runtime libraries.

**NONE**
:   Reject **-r** with an error before compilation or output writing. Native compilation and IR output remain available.

# EXAMPLES

Compile and save `test.out` (`test.exe` on Windows) beside `test.cps`:

```sh
cpsc test.cps
```

Choose the executable's output path:

```sh
cpsc test.cps -o result
```

Save LLVM IR as `test.ll` beside `test.cps`:

```sh
cpsc test.cps -S
```

Run without saving output:

```sh
cpsc test.cps -r
```

Save IR and run it:

```sh
cpsc test.cps -r -S -o result.ll
```

Save a native program and run it on Unix:

```sh
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**
:   Compilation succeeded, or **-h** printed the documentation entry point.

**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. 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 error. Runtime check failures print the source line and error reason to standard error before throwing and can be handled with TRY/CATCH/ENDTRY.

# NOTES

Compiler diagnostics go to stderr in the gcc layout `file:line: error: message`, where `file` is the source path as given on the command line; diagnostics that are not tied to a source file start with `cpsc:`. 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. Runtime diagnostics of the compiled program (for example `[Fatal] line N: ...` and `Unhandled exception. Program terminated.`) are also written to stderr, so `OUTPUT` text alone appears on stdout.

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.

Generated IR uses the C++ exception ABI. Native binaries need the C++ runtime; EMBEDDED includes it, while PATH uses the runtime available to `lli`. Nightly CI runs embedded exception tests on Linux, Windows and macOS with LLVM 23.

# FILES

*cache directory*/cpsc/std-*hash*
:   Per-user cache of the embedded standard library sources and objects, where *cache directory* is `$XDG_CACHE_HOME` or `~/.cache` on Linux, `~/Library/Caches` on macOS and the local application data directory on Windows. Directories are named by a hash of their content, files are replaced atomically, and `cpsc` never deletes them; they may be removed at any time. If no cache directory can be created, `cpsc` extracts to a temporary directory and removes it on exit.

# SEE ALSO

[cpsc-language-overview(7)](language/cpsc-language-overview.7.md) describes supported syntax and links to the keyword, builtin and standard-library function manuals.