Compare commits
3 Commits
f76a1fcfd4
...
e2688b49ea
| Author | SHA1 | Date | |
|---|---|---|---|
| e2688b49ea | |||
| 6aafab47a2 | |||
| 6d3ded49bf |
170
README.md
@@ -5,53 +5,20 @@
|
|||||||
|
|
||||||
## Example code
|
## Example code
|
||||||
### Hello World
|
### Hello World
|
||||||
```
|

|
||||||
DESIGNA x VT "Hello World!"
|
|
||||||
DICE(x)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Recursive Fibonacci number function
|
### Recursive Fibonacci number function
|
||||||
|
|
||||||
```
|

|
||||||
DEFINI fib(x) VT {
|
|
||||||
SI x EST NVLLVS TVNC {
|
|
||||||
REDI(NVLLVS)
|
|
||||||
} ALVID SI x EST I TVNC {
|
|
||||||
REDI(I)
|
|
||||||
} ALVID {
|
|
||||||
REDI(INVOCA fib(x-II) + INVOCA fib(x-I))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Number guessing game
|
### Number guessing game
|
||||||
|
|
||||||
```
|

|
||||||
CVM FORS
|
|
||||||
|
|
||||||
DESIGNA correct VT FORTIS_NVMERVS(I,C)
|
|
||||||
DESIGNA gvess VT NVLLVS
|
|
||||||
|
|
||||||
DVM FALSITAS FACE {
|
|
||||||
DESIGNA gvess VT AVDI_NVMERVS()
|
|
||||||
SI gvess MINVS correct TVNC {
|
|
||||||
DICE("Too low!")
|
|
||||||
} ALVID SI gvess PLVS correct TVNC {
|
|
||||||
DICE("Too high!")
|
|
||||||
} ALVID {
|
|
||||||
ERVMPE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DICE("You guessed correctly!")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
Variables are set with the `DESIGNA` and `VT` keywords. Type is inferred.
|
Variables are set with the `DESIGNA` and `VT` keywords. Type is inferred.
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT XXVI
|
|
||||||
```
|
|
||||||
|
|
||||||
Variable can consist of lower-case letters, numbers, as well as `_`.
|
Variable can consist of lower-case letters, numbers, as well as `_`.
|
||||||
|
|
||||||
@@ -63,15 +30,11 @@ Variable can consist of lower-case letters, numbers, as well as `_`.
|
|||||||
|
|
||||||
Strings are written as text in quotes (`'` or `"`).
|
Strings are written as text in quotes (`'` or `"`).
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT "this is a string"
|
|
||||||
```
|
|
||||||
|
|
||||||
Strings are concatenated with `&`:
|
Strings are concatenated with `&`:
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA greeting VT "Hello, " & "world!"
|
|
||||||
```
|
|
||||||
|
|
||||||
`NVLLVS` coerces to an empty string when used with `&`. Note: `+` is for arithmetic only — using it on strings raises an error.
|
`NVLLVS` coerces to an empty string when used with `&`. Note: `+` is for arithmetic only — using it on strings raises an error.
|
||||||
|
|
||||||
@@ -106,22 +69,17 @@ Booleans are denoted with the keywords `VERITAS` for true and `FALSITAS` for fal
|
|||||||
### Arrays
|
### Arrays
|
||||||
Arrays are defined using square brackets (`[]`) and commas (`,`):
|
Arrays are defined using square brackets (`[]`) and commas (`,`):
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT [I, II, III]
|
|
||||||
```
|
|
||||||
|
|
||||||
An array of integers can also be initialized with the `VSQVE` keyword:
|
An array of integers can also be initialized with the `VSQVE` keyword:
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT [I VSQVE X]
|
|
||||||
```
|
|
||||||
|
|
||||||
Individual elements can be accessed by index using square brackets. Indexing is 1-based, so `I` refers to the first element:
|
Individual elements can be accessed by index using square brackets. Indexing is 1-based, so `I` refers to the first element:
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT [I, II, III]
|
|
||||||
DICE(x[I])
|
|
||||||
|
|
||||||
|
```
|
||||||
> I
|
> I
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -129,17 +87,7 @@ DICE(x[I])
|
|||||||
### SI/TVNC
|
### SI/TVNC
|
||||||
If-then statements are denoted with the keywords `SI` (if) and `TVNC` (then). Thus, the code
|
If-then statements are denoted with the keywords `SI` (if) and `TVNC` (then). Thus, the code
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT VERITAS
|
|
||||||
SI x TVNC {
|
|
||||||
DICE(I)
|
|
||||||
REDI(NVLLVS)
|
|
||||||
}
|
|
||||||
|
|
||||||
DICE(NVLLVS)
|
|
||||||
|
|
||||||
> I
|
|
||||||
```
|
|
||||||
|
|
||||||
Will return `I` (1), as the conditional evaluates `x` to be true.
|
Will return `I` (1), as the conditional evaluates `x` to be true.
|
||||||
|
|
||||||
@@ -150,29 +98,17 @@ In conditionals, `EST` functions as an equality evaluation, and `MINVS` (<) and
|
|||||||
|
|
||||||
When using `SI`/`TVNC` statements, you can also use `ALVID` as an "else".
|
When using `SI`/`TVNC` statements, you can also use `ALVID` as an "else".
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT VERITAS
|
|
||||||
SI x TVNC {
|
|
||||||
DICE(I)
|
|
||||||
} ALVID {
|
|
||||||
DICE(NVLLVS)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
```
|
||||||
> I
|
> I
|
||||||
```
|
```
|
||||||
|
|
||||||
`SI` statements may follow immediately after `ALVID`.
|
`SI` statements may follow immediately after `ALVID`.
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT II
|
|
||||||
SI x EST I TVNC {
|
|
||||||
DICE(I)
|
|
||||||
} ALVID SI x EST II TVNC {
|
|
||||||
DICE(II)
|
|
||||||
} ALVID {
|
|
||||||
DICE(III)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
```
|
||||||
> II
|
> II
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -180,51 +116,34 @@ SI x EST I TVNC {
|
|||||||
|
|
||||||
The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used as a boolean "or".
|
The keyword `ET` can be used as a boolean "and". The keyword `AVT` can be used as a boolean "or".
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT VERITAS
|
|
||||||
DESIGNA y VT FALSITAS
|
|
||||||
SI x ET y TVNC {
|
|
||||||
DICE(I)
|
|
||||||
} ALVID SI x AVT y TVNC {
|
|
||||||
DICE(II)
|
|
||||||
} ALVID {
|
|
||||||
DICE(III)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
```
|
||||||
> II
|
> II
|
||||||
```
|
```
|
||||||
|
|
||||||
## Loops
|
## Loops
|
||||||
### DONICVM loops
|
### DONICVM loops
|
||||||
|
|
||||||
```
|

|
||||||
DESIGNA x VT NVLLVS
|
|
||||||
DONICVM y VT NVLLVS VSQVE X FACE {
|
|
||||||
DESIGNA x VT x + y
|
|
||||||
}
|
|
||||||
DICE(x)
|
|
||||||
|
|
||||||
|
```
|
||||||
> XLV
|
> XLV
|
||||||
```
|
```
|
||||||
|
|
||||||
### DVM loops
|
### DVM loops
|
||||||
```
|
|
||||||
DESIGNA x VT NVLLVS
|
|
||||||
DVM x PLVS X FACE {
|
|
||||||
DESIGNA x VT x+I
|
|
||||||
}
|
|
||||||
DICE(x)
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```
|
||||||
> XI
|
> XI
|
||||||
```
|
```
|
||||||
|
|
||||||
### PER loops
|
### PER loops
|
||||||
```
|
|
||||||
DESIGNA x VT [I, II, III, IV, V]
|
|
||||||
PER y IN x FACE {
|
|
||||||
DICE(y)
|
|
||||||
}
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```
|
||||||
> I
|
> I
|
||||||
> II
|
> II
|
||||||
> III
|
> III
|
||||||
@@ -237,34 +156,51 @@ Functions are defined with the `DEFINI` and `VT` keywords. The `REDI` keyword is
|
|||||||
|
|
||||||
Calling a function is done with the `INVOCA` keyword.
|
Calling a function is done with the `INVOCA` keyword.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
```
|
```
|
||||||
DEFINI square(x) VT {
|
|
||||||
REDI(x*x)
|
|
||||||
}
|
|
||||||
|
|
||||||
DICE(INVOCA square(XI))
|
|
||||||
|
|
||||||
> CXXI
|
> CXXI
|
||||||
```
|
```
|
||||||
|
|
||||||
## Built-ins
|
## Built-ins
|
||||||
### DICE
|
### DICE
|
||||||
|
`DICE value ...`
|
||||||
|
|
||||||
|
Prints one or more values to stdout, space-separated, with integers rendered as Roman numerals. Returns the printed string.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### AVDI
|
### AVDI
|
||||||
|
`AVDI()`
|
||||||
|
|
||||||
|
Reads one line from stdin and returns it as a string.
|
||||||
|
|
||||||
### AVDI_NVMERVS
|
### AVDI_NVMERVS
|
||||||
|
`AVDI_NVMERVS()`
|
||||||
|
|
||||||
|
Reads one line from stdin, parses it as a Roman numeral, and returns it as an integer. Raises an error if the input is not a valid numeral.
|
||||||
|
|
||||||
### ERVMPE
|
### ERVMPE
|
||||||
|
`ERVMPE`
|
||||||
|
|
||||||
|
Breaks out of the current loop (`DVM` or `PER`). Has no meaningful return value.
|
||||||
|
|
||||||
### LONGITVDO
|
### LONGITVDO
|
||||||
|
`LONGITVDO array`
|
||||||
|
|
||||||
|
Returns the length of `array` as an integer.
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
Modules are additions to the base `CENTVRION` syntax. They add or change certain features. Modules are included in your code by having
|
Modules are additions to the base `CENTVRION` syntax. They add or change certain features. Modules are included in your code by having
|
||||||
|
|
||||||
```CVM %MODVLE NAME%```
|

|
||||||
|
|
||||||
In the beginning of your source file.
|
In the beginning of your source file.
|
||||||
|
|
||||||
Vnlike many other programming languages with modules, the modules in `CENTVRION` are not libraries that can be "imported" from other scripts written in the language. They are features of the compiler, disabled by default.
|
Vnlike many other programming languages with modules, the modules in `CENTVRION` are not libraries that can be "imported" from other scripts written in the language. They are features of the compiler, disabled by default.
|
||||||
|
|
||||||
### FORS
|
### FORS
|
||||||
```CVM FORS```
|

|
||||||
|
|
||||||
The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 2 new built-in functions: `FORTIS_NVMERVS int int` and `FORTIS_ELECTIONIS ['a]`.
|
The `FORS` module allows you to add randomness to your `CENTVRION` program. It adds 2 new built-in functions: `FORTIS_NVMERVS int int` and `FORTIS_ELECTIONIS ['a]`.
|
||||||
|
|
||||||
@@ -273,7 +209,7 @@ The `FORS` module allows you to add randomness to your `CENTVRION` program. It a
|
|||||||
`FORTIS_ELECTIONIS ['a]` picks a random element from the given array. `FORTIS_ELECTIONIS array` is identical to ```array[FORTIS_NVMERVS NVLLVS ((LONGITVDO array)-I)]```.
|
`FORTIS_ELECTIONIS ['a]` picks a random element from the given array. `FORTIS_ELECTIONIS array` is identical to ```array[FORTIS_NVMERVS NVLLVS ((LONGITVDO array)-I)]```.
|
||||||
|
|
||||||
### FRACTIO
|
### FRACTIO
|
||||||
```CVM FRACTIO```
|

|
||||||
|
|
||||||
The `FRACTIO` module adds floats, in the form of base 12 fractions.
|
The `FRACTIO` module adds floats, in the form of base 12 fractions.
|
||||||
|
|
||||||
@@ -286,7 +222,7 @@ The symbol `|` can be used to denote that the following fraction symbols are 1 "
|
|||||||
A single "set" of fraction symbols can only represent up to 11/12, as 12/12 can be written as 1.
|
A single "set" of fraction symbols can only represent up to 11/12, as 12/12 can be written as 1.
|
||||||
|
|
||||||
### MAGNVM
|
### MAGNVM
|
||||||
```CVM MAGNVM```
|

|
||||||
|
|
||||||
`MAGNVM` adds the ability to write integers larger than `MMMCMXCIX` (3.999) in your code, by adding the thousands operator, "`_`".
|
`MAGNVM` adds the ability to write integers larger than `MMMCMXCIX` (3.999) in your code, by adding the thousands operator, "`_`".
|
||||||
|
|
||||||
@@ -295,6 +231,6 @@ When `_` is added _after_ a numeric symbol, the symbol becomes 1.000 times large
|
|||||||
All integer symbols except `I` may be given a `_`.
|
All integer symbols except `I` may be given a `_`.
|
||||||
|
|
||||||
### SVBNVLLA
|
### SVBNVLLA
|
||||||
```CVM SVBNVLLA```
|

|
||||||
|
|
||||||
The `SVBNVLLA` module adds the ability to write negative numbers as `-II` instead of `NVLLVS-II`.
|
The `SVBNVLLA` module adds the ability to write negative numbers as `-II` instead of `NVLLVS-II`.
|
||||||
|
|||||||
@@ -679,13 +679,19 @@ class SiStatement(Node):
|
|||||||
|
|
||||||
def _eval(self, vtable):
|
def _eval(self, vtable):
|
||||||
vtable, cond = self.test.eval(vtable)
|
vtable, cond = self.test.eval(vtable)
|
||||||
|
if not isinstance(cond, ValBool):
|
||||||
|
raise CentvrionError("SI condition must be a boolean")
|
||||||
last_val = ValNul()
|
last_val = ValNul()
|
||||||
if cond:
|
if cond:
|
||||||
for statement in self.statements:
|
for statement in self.statements:
|
||||||
vtable, last_val = statement.eval(vtable)
|
vtable, last_val = statement.eval(vtable)
|
||||||
|
if vtable["#return"] is not None:
|
||||||
|
break
|
||||||
elif self.else_part:
|
elif self.else_part:
|
||||||
for statement in self.else_part:
|
for statement in self.else_part:
|
||||||
vtable, last_val = statement.eval(vtable)
|
vtable, last_val = statement.eval(vtable)
|
||||||
|
if vtable["#return"] is not None:
|
||||||
|
break
|
||||||
return vtable, last_val
|
return vtable, last_val
|
||||||
|
|
||||||
|
|
||||||
@@ -710,16 +716,22 @@ class DumStatement(Node):
|
|||||||
def _eval(self, vtable):
|
def _eval(self, vtable):
|
||||||
last_val = ValNul()
|
last_val = ValNul()
|
||||||
vtable, cond = self.test.eval(vtable)
|
vtable, cond = self.test.eval(vtable)
|
||||||
|
if not isinstance(cond, ValBool):
|
||||||
|
raise CentvrionError("DVM condition must be a boolean")
|
||||||
while not cond:
|
while not cond:
|
||||||
for statement in self.statements:
|
for statement in self.statements:
|
||||||
vtable, val = statement.eval(vtable)
|
vtable, val = statement.eval(vtable)
|
||||||
if vtable["#break"]:
|
if vtable["#break"] or vtable["#return"] is not None:
|
||||||
break
|
break
|
||||||
last_val = val
|
last_val = val
|
||||||
if vtable["#break"]:
|
if vtable["#break"]:
|
||||||
vtable["#break"] = False
|
vtable["#break"] = False
|
||||||
break
|
break
|
||||||
|
if vtable["#return"] is not None:
|
||||||
|
break
|
||||||
vtable, cond = self.test.eval(vtable)
|
vtable, cond = self.test.eval(vtable)
|
||||||
|
if not isinstance(cond, ValBool):
|
||||||
|
raise CentvrionError("DVM condition must be a boolean")
|
||||||
return vtable, last_val
|
return vtable, last_val
|
||||||
|
|
||||||
|
|
||||||
@@ -753,12 +765,14 @@ class PerStatement(Node):
|
|||||||
vtable[variable_name] = item
|
vtable[variable_name] = item
|
||||||
for statement in self.statements:
|
for statement in self.statements:
|
||||||
vtable, val = statement.eval(vtable)
|
vtable, val = statement.eval(vtable)
|
||||||
if vtable["#break"]:
|
if vtable["#break"] or vtable["#return"] is not None:
|
||||||
break
|
break
|
||||||
last_val = val
|
last_val = val
|
||||||
if vtable["#break"]:
|
if vtable["#break"]:
|
||||||
vtable["#break"] = False
|
vtable["#break"] = False
|
||||||
break
|
break
|
||||||
|
if vtable["#return"] is not None:
|
||||||
|
break
|
||||||
return vtable, last_val
|
return vtable, last_val
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
snippets/alvid.cent
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
DESIGNA x VT VERITAS
|
||||||
|
SI x TVNC {
|
||||||
|
DICE(I)
|
||||||
|
} ALVID {
|
||||||
|
DICE(NVLLVS)
|
||||||
|
}
|
||||||
BIN
snippets/alvid.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
8
snippets/alvid_si.cent
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
DESIGNA x VT II
|
||||||
|
SI x EST I TVNC {
|
||||||
|
DICE(I)
|
||||||
|
} ALVID SI x EST II TVNC {
|
||||||
|
DICE(II)
|
||||||
|
} ALVID {
|
||||||
|
DICE(III)
|
||||||
|
}
|
||||||
BIN
snippets/alvid_si.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
2
snippets/array_index.cent
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DESIGNA x VT [I, II, III]
|
||||||
|
DICE(x[I])
|
||||||
BIN
snippets/array_index.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
1
snippets/array_literal.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DESIGNA x VT [I, II, III]
|
||||||
BIN
snippets/array_literal.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
1
snippets/array_vsqve.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DESIGNA x VT [I VSQVE X]
|
||||||
BIN
snippets/array_vsqve.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
9
snippets/boolean_ops.cent
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
DESIGNA x VT VERITAS
|
||||||
|
DESIGNA y VT FALSITAS
|
||||||
|
SI x ET y TVNC {
|
||||||
|
DICE(I)
|
||||||
|
} ALVID SI x AVT y TVNC {
|
||||||
|
DICE(II)
|
||||||
|
} ALVID {
|
||||||
|
DICE(III)
|
||||||
|
}
|
||||||
BIN
snippets/boolean_ops.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
2
snippets/dice.cent
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DICE("Hello, world!")
|
||||||
|
DICE(I, II, III)
|
||||||
BIN
snippets/dice.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
5
snippets/donicvm.cent
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
DESIGNA x VT NVLLVS
|
||||||
|
DONICVM y VT NVLLVS VSQVE X FACE {
|
||||||
|
DESIGNA x VT x + y
|
||||||
|
}
|
||||||
|
DICE(x)
|
||||||
BIN
snippets/donicvm.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
5
snippets/dvm.cent
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
DESIGNA x VT NVLLVS
|
||||||
|
DVM x PLVS X FACE {
|
||||||
|
DESIGNA x VT x+I
|
||||||
|
}
|
||||||
|
DICE(x)
|
||||||
BIN
snippets/dvm.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
9
snippets/fibonacci.cent
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
DEFINI fib(x) VT {
|
||||||
|
SI x EST NVLLVS TVNC {
|
||||||
|
REDI(NVLLVS)
|
||||||
|
} ALVID SI x EST I TVNC {
|
||||||
|
REDI(I)
|
||||||
|
} ALVID {
|
||||||
|
REDI(INVOCA fib(x-II) + INVOCA fib(x-I))
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
snippets/fibonacci.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
1
snippets/fors.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CVM FORS
|
||||||
BIN
snippets/fors.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
1
snippets/fractio.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CVM FRACTIO
|
||||||
BIN
snippets/fractio.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
5
snippets/function.cent
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
DEFINI sqvare(x) VT {
|
||||||
|
REDI(x*x)
|
||||||
|
}
|
||||||
|
|
||||||
|
DICE(INVOCA sqvare(XI))
|
||||||
BIN
snippets/function.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
17
snippets/guessing.cent
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
CVM FORS
|
||||||
|
|
||||||
|
DESIGNA correct VT FORTIS_NVMERVS(I,C)
|
||||||
|
DESIGNA gvess VT NVLLVS
|
||||||
|
|
||||||
|
DVM FALSITAS FACE {
|
||||||
|
DESIGNA gvess VT AVDI_NVMERVS()
|
||||||
|
SI gvess MINVS correct TVNC {
|
||||||
|
DICE("Too low!")
|
||||||
|
} ALVID SI gvess PLVS correct TVNC {
|
||||||
|
DICE("Too high!")
|
||||||
|
} ALVID {
|
||||||
|
ERVMPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DICE("You guessed correctly!")
|
||||||
BIN
snippets/guessing.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
2
snippets/hello_world.cent
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DESIGNA x VT "Hello World!"
|
||||||
|
DICE(x)
|
||||||
BIN
snippets/hello_world.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
1
snippets/magnvm.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CVM MAGNVM
|
||||||
BIN
snippets/magnvm.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
1
snippets/module_decl.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CVM MODVLE_NOMEN
|
||||||
BIN
snippets/module_decl.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
4
snippets/per.cent
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
DESIGNA x VT [I, II, III, IV, V]
|
||||||
|
PER y IN x FACE {
|
||||||
|
DICE(y)
|
||||||
|
}
|
||||||
BIN
snippets/per.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
7
snippets/si_tvnc.cent
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
DESIGNA x VT VERITAS
|
||||||
|
SI x TVNC {
|
||||||
|
DICE(I)
|
||||||
|
REDI(NVLLVS)
|
||||||
|
}
|
||||||
|
|
||||||
|
DICE(NVLLVS)
|
||||||
BIN
snippets/si_tvnc.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
1
snippets/string_concat.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DESIGNA greeting VT "Hello, " & "world!"
|
||||||
BIN
snippets/string_concat.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
1
snippets/string_literal.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DESIGNA x VT "this is a string"
|
||||||
BIN
snippets/string_literal.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
1
snippets/svbnvlla.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CVM SVBNVLLA
|
||||||
BIN
snippets/svbnvlla.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
77
snippets/syntax/centvrion.sublime-syntax
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
name: Centvrion
|
||||||
|
file_extensions:
|
||||||
|
- cent
|
||||||
|
scope: source.centvrion
|
||||||
|
|
||||||
|
contexts:
|
||||||
|
main:
|
||||||
|
- include: comments
|
||||||
|
- include: strings
|
||||||
|
- include: fractions
|
||||||
|
- include: numerals
|
||||||
|
- include: constants
|
||||||
|
- include: builtins
|
||||||
|
- include: modules
|
||||||
|
- include: keywords
|
||||||
|
- include: operators
|
||||||
|
- include: identifiers
|
||||||
|
|
||||||
|
comments:
|
||||||
|
- match: '//[^\n]*'
|
||||||
|
scope: comment.line.centvrion
|
||||||
|
- match: '/\*'
|
||||||
|
scope: comment.block.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: comment.block.centvrion
|
||||||
|
- match: '\*/'
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
strings:
|
||||||
|
- match: '"'
|
||||||
|
scope: string.quoted.double.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: string.quoted.double.centvrion
|
||||||
|
- match: '"'
|
||||||
|
pop: true
|
||||||
|
- match: "'"
|
||||||
|
scope: string.quoted.single.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: string.quoted.single.centvrion
|
||||||
|
- match: "'"
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
fractions:
|
||||||
|
- match: '\b[IVXLCDM][IVXLCDM_]*(?:S[S:.|]*|:[S:.|]+|\.[S:.|]*)'
|
||||||
|
scope: constant.numeric.fraction.centvrion
|
||||||
|
- match: '(?<![IVXLCDM_])(?:S[S:.|]+|:[S:.|]+)'
|
||||||
|
scope: constant.numeric.fraction.centvrion
|
||||||
|
|
||||||
|
numerals:
|
||||||
|
- match: '\b[IVXLCDM][IVXLCDM_]*\b'
|
||||||
|
scope: constant.numeric.centvrion
|
||||||
|
|
||||||
|
constants:
|
||||||
|
- match: '\b(VERITAS|FALSITAS|NVLLVS)\b'
|
||||||
|
scope: constant.language.centvrion
|
||||||
|
|
||||||
|
builtins:
|
||||||
|
- match: '\b(AVDI_NVMERVS|AVDI|DICE|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LONGITVDO)\b'
|
||||||
|
scope: support.function.builtin.centvrion
|
||||||
|
|
||||||
|
modules:
|
||||||
|
- match: '\b(FORS|FRACTIO|MAGNVM|SVBNVLLA)\b'
|
||||||
|
scope: support.class.module.centvrion
|
||||||
|
|
||||||
|
keywords:
|
||||||
|
- match: '\b(ALVID|AVT|DEFINI|DESIGNA|DONICVM|DVM|ERVMPE|EST|ET|FACE|INVOCA|IN|MINVS|NON|PER|PLVS|REDI|SI|TVNC|VSQVE|VT|CVM)\b'
|
||||||
|
scope: keyword.control.centvrion
|
||||||
|
|
||||||
|
operators:
|
||||||
|
- match: '[+\-*/&]'
|
||||||
|
scope: keyword.operator.centvrion
|
||||||
|
|
||||||
|
identifiers:
|
||||||
|
- match: '[abcdefghiklmnopqrstvxyz_]+'
|
||||||
|
scope: variable.other.centvrion
|
||||||
77
snippets/syntaxes/centvrion.sublime-syntax
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
name: Centvrion
|
||||||
|
file_extensions:
|
||||||
|
- cent
|
||||||
|
scope: source.centvrion
|
||||||
|
|
||||||
|
contexts:
|
||||||
|
main:
|
||||||
|
- include: comments
|
||||||
|
- include: strings
|
||||||
|
- include: fractions
|
||||||
|
- include: numerals
|
||||||
|
- include: constants
|
||||||
|
- include: builtins
|
||||||
|
- include: modules
|
||||||
|
- include: keywords
|
||||||
|
- include: operators
|
||||||
|
- include: identifiers
|
||||||
|
|
||||||
|
comments:
|
||||||
|
- match: '//[^\n]*'
|
||||||
|
scope: comment.line.centvrion
|
||||||
|
- match: '/\*'
|
||||||
|
scope: comment.block.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: comment.block.centvrion
|
||||||
|
- match: '\*/'
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
strings:
|
||||||
|
- match: '"'
|
||||||
|
scope: string.quoted.double.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: string.quoted.double.centvrion
|
||||||
|
- match: '"'
|
||||||
|
pop: true
|
||||||
|
- match: "'"
|
||||||
|
scope: string.quoted.single.centvrion
|
||||||
|
push:
|
||||||
|
- meta_scope: string.quoted.single.centvrion
|
||||||
|
- match: "'"
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
fractions:
|
||||||
|
- match: '\b[IVXLCDM][IVXLCDM_]*(?:S[S:.|]*|:[S:.|]+|\.[S:.|]*)'
|
||||||
|
scope: constant.numeric.fraction.centvrion
|
||||||
|
- match: '(?<![IVXLCDM_])(?:S[S:.|]+|:[S:.|]+)'
|
||||||
|
scope: constant.numeric.fraction.centvrion
|
||||||
|
|
||||||
|
numerals:
|
||||||
|
- match: '\b[IVXLCDM][IVXLCDM_]*\b'
|
||||||
|
scope: constant.numeric.centvrion
|
||||||
|
|
||||||
|
constants:
|
||||||
|
- match: '\b(VERITAS|FALSITAS|NVLLVS)\b'
|
||||||
|
scope: constant.language.centvrion
|
||||||
|
|
||||||
|
builtins:
|
||||||
|
- match: '\b(AVDI_NVMERVS|AVDI|DICE|FORTIS_NVMERVS|FORTIS_ELECTIONIS|LONGITVDO)\b'
|
||||||
|
scope: support.function.builtin.centvrion
|
||||||
|
|
||||||
|
modules:
|
||||||
|
- match: '\b(FORS|FRACTIO|MAGNVM|SVBNVLLA)\b'
|
||||||
|
scope: support.class.module.centvrion
|
||||||
|
|
||||||
|
keywords:
|
||||||
|
- match: '\b(ALVID|AVT|DEFINI|DESIGNA|DONICVM|DVM|ERVMPE|EST|ET|FACE|INVOCA|IN|MINVS|NON|PER|PLVS|REDI|SI|TVNC|VSQVE|VT|CVM)\b'
|
||||||
|
scope: keyword.control.centvrion
|
||||||
|
|
||||||
|
operators:
|
||||||
|
- match: '[+\-*/&]'
|
||||||
|
scope: keyword.operator.centvrion
|
||||||
|
|
||||||
|
identifiers:
|
||||||
|
- match: '[abcdefghiklmnopqrstvxyz_]+'
|
||||||
|
scope: variable.other.centvrion
|
||||||
1
snippets/variable.cent
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DESIGNA x VT XXVI
|
||||||
BIN
snippets/variable.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
62
tests.py
@@ -401,6 +401,11 @@ error_tests = [
|
|||||||
("PER i IN I FACE { DICE(i) }", CentvrionError), # PER over non-array
|
("PER i IN I FACE { DICE(i) }", CentvrionError), # PER over non-array
|
||||||
("LONGITVDO(I)", CentvrionError), # LONGITVDO on non-array
|
("LONGITVDO(I)", CentvrionError), # LONGITVDO on non-array
|
||||||
("DESIGNA x VT I\nINVOCA x ()", CentvrionError), # invoking a non-function
|
("DESIGNA x VT I\nINVOCA x ()", CentvrionError), # invoking a non-function
|
||||||
|
("SI I TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: int
|
||||||
|
("DESIGNA z VT I - I\nSI z TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: zero int
|
||||||
|
("SI [I] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: non-empty list
|
||||||
|
("SI [] TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: empty list
|
||||||
|
("DESIGNA x VT I\nDVM x FACE {\nDESIGNA x VT x + I\n}", CentvrionError), # non-bool DVM condition: int
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestErrors(unittest.TestCase):
|
class TestErrors(unittest.TestCase):
|
||||||
@@ -557,30 +562,10 @@ class TestDiceTypes(unittest.TestCase):
|
|||||||
run_test(self, source, nodes, value, output)
|
run_test(self, source, nodes, value, output)
|
||||||
|
|
||||||
|
|
||||||
# --- SI/DVM: truthiness of non-bool conditions ---
|
# --- SI/DVM: boolean condition enforcement ---
|
||||||
|
|
||||||
truthiness_tests = [
|
dvm_bool_condition_tests = [
|
||||||
# nonzero int is truthy
|
# DVM exits when condition becomes true (boolean comparison)
|
||||||
("SI I TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr",
|
|
||||||
Program([], [SiStatement(Numeral("I"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
|
|
||||||
ValInt(1)),
|
|
||||||
# zero int is falsy
|
|
||||||
("DESIGNA z VT I - I\nSI z TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr",
|
|
||||||
Program([], [
|
|
||||||
Designa(ID("z"), BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS")),
|
|
||||||
SiStatement(ID("z"), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]),
|
|
||||||
ExpressionStatement(ID("r")),
|
|
||||||
]),
|
|
||||||
ValInt(2)),
|
|
||||||
# non-empty list is truthy
|
|
||||||
("SI [I] TVNC { DESIGNA r VT I } ALVID { DESIGNA r VT II }\nr",
|
|
||||||
Program([], [SiStatement(DataArray([Numeral("I")]), [Designa(ID("r"), Numeral("I"))], [Designa(ID("r"), Numeral("II"))]), ExpressionStatement(ID("r"))]),
|
|
||||||
ValInt(1)),
|
|
||||||
# empty list is falsy
|
|
||||||
("SI [] TVNC { DESIGNA r VT II } ALVID { DESIGNA r VT I }\nr",
|
|
||||||
Program([], [SiStatement(DataArray([]), [Designa(ID("r"), Numeral("II"))], [Designa(ID("r"), Numeral("I"))]), ExpressionStatement(ID("r"))]),
|
|
||||||
ValInt(1)),
|
|
||||||
# DVM exits when condition becomes truthy
|
|
||||||
(
|
(
|
||||||
"DESIGNA x VT I\nDVM x PLVS III FACE {\nDESIGNA x VT x + I\n}\nx",
|
"DESIGNA x VT I\nDVM x PLVS III FACE {\nDESIGNA x VT x + I\n}\nx",
|
||||||
Program([], [
|
Program([], [
|
||||||
@@ -592,12 +577,13 @@ truthiness_tests = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestTruthiness(unittest.TestCase):
|
class TestDvmBoolCondition(unittest.TestCase):
|
||||||
@parameterized.expand(truthiness_tests)
|
@parameterized.expand(dvm_bool_condition_tests)
|
||||||
def test_truthiness(self, source, nodes, value):
|
def test_dvm_bool_condition(self, source, nodes, value):
|
||||||
run_test(self, source, nodes, value)
|
run_test(self, source, nodes, value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- Arithmetic: edge cases ---
|
# --- Arithmetic: edge cases ---
|
||||||
|
|
||||||
arithmetic_edge_tests = [
|
arithmetic_edge_tests = [
|
||||||
@@ -741,6 +727,30 @@ function_edge_tests = [
|
|||||||
]),
|
]),
|
||||||
ValInt(10),
|
ValInt(10),
|
||||||
),
|
),
|
||||||
|
# REDI inside SI exits function, skips remaining statements in block
|
||||||
|
(
|
||||||
|
"DEFINI f () VT {\nSI VERITAS TVNC {\nREDI (I)\nREDI (II)\n}\n}\nINVOCA f ()",
|
||||||
|
None,
|
||||||
|
ValInt(1),
|
||||||
|
),
|
||||||
|
# REDI inside DVM exits loop and function
|
||||||
|
(
|
||||||
|
"DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FACE {\nREDI (x)\n}\n}\nINVOCA f ()",
|
||||||
|
None,
|
||||||
|
ValInt(1),
|
||||||
|
),
|
||||||
|
# REDI inside PER exits loop and function
|
||||||
|
(
|
||||||
|
"DEFINI f () VT {\nPER x IN [I, II, III] FACE {\nSI x EST II TVNC {\nREDI (x)\n}\n}\n}\nINVOCA f ()",
|
||||||
|
None,
|
||||||
|
ValInt(2),
|
||||||
|
),
|
||||||
|
# REDI inside nested loops exits all loops and function
|
||||||
|
(
|
||||||
|
"DEFINI f () VT {\nDESIGNA x VT I\nDVM FALSITAS FACE {\nDVM FALSITAS FACE {\nREDI (x)\n}\n}\n}\nINVOCA f ()",
|
||||||
|
None,
|
||||||
|
ValInt(1),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestFunctionEdge(unittest.TestCase):
|
class TestFunctionEdge(unittest.TestCase):
|
||||||
|
|||||||