Codegen is a generic programming language designed to be transpiled into multiple target languages including C++, Java, JavaScript, Perl, Python, Rust, and Swift. Programs are written in .src files using a keyword-prefixed syntax that maps to common programming constructs across all supported targets.
Every Codegen program has a standard structure:
BeginProgram: ProgramName
BeginMain:
... statements ...
EndMain
EndProgram
Global declarations (variables, functions, classes, enums) can appear between BeginProgram: and BeginMain:.
BeginProgram: HelloWorld
BeginMain:
PrintLine: "Hello, World!"
EndMain
EndProgram
Pragmas configure compiler behavior and are placed at the top of the file, before BeginProgram:.
Pragma: Name
Pragma: Name = Value
| Pragma | Description |
|---|---|
UseUnicode |
Enable Unicode/codepoint support |
UseCmdArgs |
Enable command-line argument handling |
UseUtils |
Include utility functions |
Pragma: UseUnicode
Pragma: UseCmdArgs
Pragma: UseUtils
BeginProgram: MyProgram
...
Single line comments are passed through to the transpiled code.
Comment: This is a single-line comment
Block comments are passed through to the transpiled code.
BeginComment:
This is a multi-line comment.
It can span several lines.
EndComment
Lines beginning with # (at column 0) are treated as Codegen source comments and are skipped. They do not get put in the transpiled code. These comments can also be placed at the end of code lines.
# This is a single-line comment that gets discarded
expr # inline comment
Scalar types are denoted with angle brackets:
| Syntax | Description |
|---|---|
<byte> |
Byte (8-bit signed) |
<short> |
Short integer (16-bit signed) |
<int> |
Integer (32-bit signed) |
<long> |
Long integer (64-bit signed) |
<float> |
Single-precision (32-bit) Floating point |
<double> |
Double-precision (64-bit) floating point |
<string> |
String (UTF-8) |
<char> |
Character (language specific) |
<char*> |
Immutable string reference |
<bool> |
Boolean |
<codepoint_t> |
Unicode codepoint (32-bit) |
<ifilehandle> |
Input file handle |
<ofilehandle> |
Output file handle |
<io_exception> |
I/O exception type |
Append ? to make any type optional (nullable):
<int>? // optional int
<string>? // optional string
≤Complex≥? // optional user type
Use ! to force-unwrap an optional value:
variable!
Lists use square bracket notation:
[<int>] // list of int
[<string>] // list of string
[[<int>]?] // list of optional lists of int (nested)
Maps use curly brace notation with key and value types separated by |:
{<string>|<string>} // map from string to string
{<int>|<double>} // map from int to double
Tuples use angle-quote notation («») with types separated by |:
«<string>|<int>» // tuple of string and int
«<int>|<double>|<string>» // tuple of int, double, and string
User types and Enumerations use the ≤≥ delimiters:
≤Complex≥ // user type Complex
≤CompassPoint≥ // user type CompassPoint
≤Color≥ // Enum type Color
ScalarDecl: <type> name = value
ScalarDecl: const <type> name = value
ScalarDecl: final <type> name = value
ScalarDecl: static <type> name = value
Multiple variables can be declared in one statement:
ScalarDecl: <int> x = 0, y = 1, z = 2
| Modifier | Description |
|---|---|
const / final |
Immutable variable |
static |
Static (class-level or global) |
auto |
Auto-inferred type (used in loops) |
Lists can be declared in various ways. The first form creates an empty expandable list. The second form creates a list initialized with values. The third form is used to assign one list to another. The final form declares a fixed size list.
ListDecl: [<type>] name // empty list
ListDecl: [<type>] name := val1, val2, val3 // initialized list
ListDecl: [<type>] name = expr // assign from expression
ListDecl: [<type>] name[size] // sized list
Maps can be declared in various ways. The first form declares an empty map. The second creates a map that is pre-initialized with values. The final form is for assigning one map to another.
MapDecl: {<keyType>|<valueType>} name // empty map
MapDecl: {<keyType>|<valueType>} name := k1=>v1, k2=>v2 // initialized map
MapDecl: {<keyType>|<valueType>} name = expr // assign from expression
Tuples are immutable so they must be intialized with values or with another tuple.
TupleDecl: «<type1>|<type2>» name := val1, val2
TupleDecl: «<type1>|<type2>|<type3>» name = expr
User defined variable types must be initialized with a value/args that would be passed to the constructor. The new form creates a dynamically allocated object.
UserTypeDecl: ≤TypeName≥ name = new TypeName(args)
UserTypeDecl: const ≤TypeName≥ name = value
UnpackTuple: tupleExpr -> var1, var2, var3
Assign: variable = expr
Assign: variable += expr
Assign: variable -= expr
Assign: variable *= expr
Assign: variable /= expr
Assign: variable %= expr
Assign: variable <<= expr
Assign: variable >>= expr
Assign: variable &= expr
Assign: variable |= expr
Assign: variable ^= expr
Assign: variable &&&= expr // string concatenation assignment
| Operator | Description |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Floating Point Division |
// |
Integer division |
% |
Modulus |
** |
Exponentiation |
| Operator | Description |
|---|---|
== |
Equal to |
!= |
Not equal to |
< |
Less than |
> |
Greater than |
<= |
Less than or equal |
>= |
Greater than or equal |
| Operator | Description |
|---|---|
eq |
String equal |
ne |
String not equal |
lt |
String less than |
gt |
String greater than |
le |
String less than or equal |
ge |
String greater than or equal |
| Operator | Description |
|---|---|
=~ |
Matches regex |
!~ |
Does not match regex |
| Operator | Description |
|---|---|
&& |
Logical AND |
|| |
Logical OR |
! |
Logical NOT |
| Operator | Description |
|---|---|
& |
Bitwise AND |
| |
Bitwise OR |
^ |
Bitwise XOR |
~ |
Bitwise NOT |
<< |
Arithmetic/Logical Left shift |
>> |
Arithmetic right shift |
>>> |
Logical right shift |
The &&& operator concatenates strings:
ScalarDecl: <string> full = first &&& " " &&& last
condition ? trueExpr : falseExpr
Print: expr
Print: expr1, expr2, expr3
PrintLine: expr
PrintLine: expr1, expr2, expr3
PrintLine: // prints just a newline
Use the format() function with positional format specifiers:
PrintLine: format("{0:d} + {1:d} = {2:d}", a, b, a + b)
PrintLine: format("{0:s} is {1:.2f}", name, value)
Format specifiers follow the pattern {index:format}:
d — integerf — floating point.Nf — floating point with N decimal placess — stringc — characterx — hexadecimalBeginIf: condition
... statements ...
ElseIf: condition
... statements ...
Else:
... statements ...
EndIf
BeginSwitch: expr
Case: value1
... statements ...
Case: value2, value3
... statements ...
Default:
... statements ...
EndSwitch
Break:
Continue:
BeginFor: auto i in XRANGE(start, end)
... statements ...
EndFor
BeginFor: <int> i in IRANGE(start, end)
... statements ...
EndFor
BeginFor: <int> i in IRANGE(start, end, step)
... statements ...
EndFor
Range functions:
XRANGE(start, end) — exclusive of end (like Python's range)XRANGE(start, end, step) — exclusive of end with stepIRANGE(start, end) — inclusive of endIRANGE(start, end, step) — inclusive with stepFRANGE(start, end, step) — floating-point rangeBeginFor: initExpr; condExpr; incrExpr
... statements ...
EndFor
BeginForEach: auto item in collection
... statements ...
EndForEach
BeginWhile: condition
... statements ...
EndWhile
BeginDoWhile:
... statements ...
EndDoWhile: condition
BeginFunction: returnType functionName(argType1 arg1, argType2 arg2)
... statements ...
Return: value
EndFunction
BeginFunction: void doSomething(<int> x)
PrintLine: x
EndFunction
BeginFunction: static void helper(<int> n)
... statements ...
EndFunction
Needed for async JavaScript functions. Has no meaning in other languages.
BeginFunction: async void readFile(<string> path) throws <io_exception>
... statements ...
EndFunction
Statement: functionName(arg1, arg2)
Expression: functionName(arg1, arg2)
BeginFunction: [<string>] reverseList([<string>] x)
ListDecl: [<string>] y
...
Return: y
EndFunction
Use inout for pass-by-reference parameters:
BeginFunction: void swap(inout <int> a, inout <int> b)
...
EndFunction
BeginFunction: void printAll(<string> first, ...)
...
EndFunction
BeginClass: ClassName extends SomeOtherClass
Private:
ScalarDecl: <type> field1
ScalarDecl: <type> field2
Public:
BeginFunction: void __INIT(<type> param1, <type> param2)
Assign: field1 = param1
Assign: field2 = param2
EndFunction
BeginFunction: <type> methodName()
Return: field1
EndFunction
EndClass
__INITPublic:, Private:, Protected:BeginClass: Child extends ParentBeginClass: MyClass implements Interface1, Interface2this keyword: Reference the current objectUserTypeDecl: ≤ClassName≥ obj = new ClassName(arg1, arg2)
Statement: obj.methodName()
ScalarDecl: <type> result = obj.methodName()
PrintLine: obj.toString()
PrintLine: a.add(b).toString()
BeginEnum: EnumName := VALUE1, VALUE2, VALUE3
BeginEnum: Color := RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4
UserTypeDecl: ≤EnumName≥ var = EnumName::VALUE1
CompassPoint::NORTH
Color::RED
| Function | Description |
|---|---|
enumToString(e) |
Convert enum value to string |
enumToInt(e) |
Convert enum value to integer |
intToEnum("EnumName", n) |
Convert integer to enum value |
BeginTry:
CanThrow: riskyOperation()
Catch: <exception_type> variableName
... handle error ...
Catch: ...
... catch-all handler ...
EndTry
Throw: <io_exception> : "Error message"
Finally is not supported by all target languages so often used in a conditional language eval.
BeginTry:
BeginFinally:
... cleanup code ...
EndFinally
CanThrow: riskyOperation()
Catch: <io_exception> ex
PrintLine: exception_msg(ex)
EndTry
BeginFunction: void readFile(<string> path) throws <io_exception>
...
EndFunction
Use CanThrow: to mark expressions that may throw exceptions:
CanThrow: await readTextFile(filespec)
CanThrow: result = dangerousFunction()
The BeginEval / EndEval construct allows language-specific code paths. This is essential because target languages sometimes require different approaches for the same operation.
BeginEval: language =~ m/py|swift/
... Python/Swift specific code ...
ElseIfEval: language =~ m/cpp|java/
... C++/Java specific code ...
ElseEval:
... default code for other languages ...
EndEval
| Expression | Description |
|---|---|
language =~ m/pattern/ |
Language matches regex |
language !~ m/pattern/ |
Language doesn't match regex |
pragma_name |
Pragma is defined/true |
!pragma_name |
Pragma is not defined/false |
pragma == value |
Pragma equals integer value |
pragma eq "value" |
Pragma equals string value |
true / false |
Boolean literals |
| Code | Language |
|---|---|
cpp |
C++ |
java |
Java |
js |
JavaScript |
pl |
Perl |
py |
Python |
rs |
Rust |
swift |
Swift |
| Function | Description |
|---|---|
char(expr) |
Convert to char |
byte(expr) |
Convert to byte |
short(expr) |
Convert to short |
int(expr) |
Convert to int |
long(expr) |
Convert to long |
int16(expr) |
Convert to 16-bit int |
int32(expr) |
Convert to 32-bit int |
int64(expr) |
Convert to 64-bit int |
double(expr) |
Convert to double |
string(expr) |
Convert to string |
| Function | Description |
|---|---|
isNull(expr) |
Check if value is null or optional value has no value |
| Function | Description |
|---|---|
listsize(list) |
Get list size |
mapsize(map) |
Get map size |
mapkeys(map) |
Get map keys |
mapkeysAsList(map) |
Get map keys as a list |
push(list, value) |
Append to list |
isEmptyMap(map) |
Check if map is empty |
mapContains(map, key) |
Check if map contains key |
mapRemove(map, key) |
Remove key from map |
listToString(list) |
Convert list to string |
mapToString(map) |
Convert map to string |
tupleToString(tuple) |
Convert tuple to string |
tuple(v1, v2, ...) |
Create a tuple |
| Function | Description |
|---|---|
strlen(str) |
Get string length (language specific) |
find(str, substr) |
Find substring position |
char_at(str, index) |
Get character at index |
codepoint_at(str, index) |
Get codepoint at index |
tolower(c) |
Convert to lowercase |
toupper(c) |
Convert to uppercase |
format(fmt, ...) |
Formatted string |
| Function | Description |
|---|---|
stoi_w_default(str, default) |
String to int with default |
stol_w_default(str, default) |
String to long with default |
stod_w_default(str, default) |
String to double with default |
| Function | Description |
|---|---|
sqrt(x) |
Square root |
pow(x, y) |
Power |
exp(x) |
Exponential |
log(x) |
Natural logarithm |
sin(x) |
Sine |
cos(x) |
Cosine |
atan(x) |
Arctangent |
abs(x) |
Absolute value |
max(a, b) |
Maximum |
min(a, b) |
Minimum |
sgn(x) |
Sign function |
pi() |
Pi constant |
| Function | Description |
|---|---|
openFileRead(path) |
Open file for reading |
close(handle) |
Close file handle |
getcodepoint(var, handle) |
Read a codepoint |
putcodepoint(cp) |
Write a codepoint |
binmode(handle) |
Set binary file I/O mode |
utf8mode(handle) |
Set UTF-8 text file I/O mode |
isBad(handle) |
Check if file handle is invalid |
| Function | Description |
|---|---|
program_arg(n) |
Get command-line argument n |
program_args_equal(n) |
Check if arg count equals n |
program_args_not_equal(n) |
Check if arg count doesn't equal n |
program_args_less_than(n) |
Check if arg count < n |
program_args_equal_or_more(n) |
Check if arg count ≥ n |
exit(code) |
Exit program with code |
| Constant | Description |
|---|---|
PROGRAM_NAME |
Program name |
ARGC |
Argument count |
EOF |
End of file marker |
STRING_NOT_FOUND |
String search not-found sentinel |
Passthrough allows embedding target-language-specific code directly:
Statement: @@@target_language_code@@@
This is typically used within BeginEval blocks for language-specific operations.
list[index]
map{key}
Tuples use 1-based indexing with angle quotes:
tuple«1» // first element
tuple«2» // second element
new ClassName(arg1, arg2)
new List [<type>](args)
new Map {<keyType>|<valueType>}(entries)
Static members and methods are accessed with the :: operator:
ClassName::MEMBER
ClassName::methodName(args)
| Statement | Description |
|---|---|
Assertion: expr |
Runtime assertion |
Assertion: expr : "message" |
Assertion with message |
Precondition: expr : "message" |
Function precondition |
Postcondition: expr : "message" |
Function postcondition |
Invariant: expr : "message" |
Loop/class invariant |
BeginFunction: ≤Complex≥ recip()
ScalarDecl: final <double> magSquared = real * real + imaginary * imaginary
Precondition: magSquared != 0. : "Can't compute reciprocal of 0+0i"
Return: new Complex(real / magSquared, -imaginary / magSquared)
EndFunction
Group statements in a block:
BeginBlock:
... statements ...
EndBlock
Debug: expr
Debug: condition : expr1, expr2
Delete: object
Sequence: HelloWorld.src | HelloWorlds.src | Sequence1.src | Sequence2.src
Selection: Selection1.src | Selection2.src | Selection3.src | Selection4.src | Selection5.src
Iteration: Iteration1.src | Iteration2.src | Iteration3.src | Iteration4.src | Iteration5.src | Iteration6.src
Assertions: Assertions1.src | Assertions2.src | Assertions3.src
Command Line Arguments: CmdLineArgs1.src | CmdLineArgs2.src | CmdLineArgs3.src
Console Input: ConsoleInput1.src | ConsoleInput2.src
Enumerations: Enums1.src | Enums2.src
Exceptions: Exceptions1.src | Exceptions2.src | Exceptions3.src | Exceptions4.src | Exceptions5.src
File I/O: FileIO1.src | FileIO2.src | FileIO3.src | FileIO4.src | FileIO5.src | FileIO6.src | FileIO7.src | FileIO8.src | FileIO9.src | FileIO10.src
Functions: Functions1.src | Functions2.src | Functions3.src | Functions4.src | Functions5.src
Lists: Lists1.src | Lists2.src | Lists3.src | Lists4.src | Lists5.src | Lists6.src
Operators: Operators1.src | Operators2.src | Operators3.src | Operators4.src | Operators5.src | Operators6.src | Operators7.src | Operators8.src
Output Formatting: OutputFormatting1.src | OutputFormatting2.src | OutputFormatting3.src | OutputFormatting4.src
Regular Expressions: RegEx1.src | RegEx2.src | RegEx3.src
Stream I/O: StreamIO1.src | StreamIO2.src | StreamIO3.src
Strings: Strings1.src | Strings2.src | Strings3.src | Strings4.src
Tuples: Tuples1.src | Tuples2.src | Tuples3.src | Tuples4.src
To generate target language source from a .src file:
./codegen.sh ProgramName cpp|java|js|pl|py|rs|swift
To compile and run the generated code:
./compile_and_run.sh ProgramName cpp|java|js|pl|py|rs|swift
©2026 Richard Lesh. All rights reserved.
Codegen | CodgenIDE | Pure Programmer | Glowing Cat Software