Releases: smuuf/primi
Releases · smuuf/primi
Primi 0.4
- New: If statements now support else clause.
- Thanks to Add else clause to IfStatement #19 by @fredsted.
- New: String literals now support proper escaping (BC break).
- You can now "escape an escape sequence" (e.g a
\n
newline) using a double backslash (e.g.\\n
) to avoid escaping. (BC break)- Previously, string literal
"\\n"
would result in a string of new-line preceeded by a backslash\
symbol. Now"\\n"
results in literal\n
.
- Previously, string literal
- Also, escape sequences were previously expanded when instantiating
String
value objects - even, for example, when it was the result of concatenating two strings"\"
and"n"
, which would then result in new string equal to"\n"
, which would be then expanded to a literal newline, which is just wrong approach. - With the new approach escape sequences are expanded only at the time of the evaluating string literals in Primi source code. It is merely a way of how string literals are interpreted.
- Example:
- As of now, concatenating
"\" + "n"
will result in string"\n"
being a literal backslash\
followed by a literal lettern
. (BC break) - A string literal
"\n"
is still expanded to a newline symbol (i.e.line feed
or decimal ASCII10
).
- As of now, concatenating
- Example:
- Currently supported escape sequences are these:
\n
: Will result in a newline.\t
: Will result in TAB character.\\
: Will result in a single backslash\
.\"
: Will result in"
in both single and double quoted string literals,\'
: Will result in'
in both single and double quoted string literals,- **All other characters with a single backslash in front of them, for example
\m
, will result in anUnrecognized string escape sequence '\m'
error. (BC break)
- Thanks to @fredsted for the original idea.
- You can now "escape an escape sequence" (e.g a
- New: Support for conditional expressions (akin to ternary operator) like
"X if (bool) else Y"
. (Yes, obviously inspired by Python.)- Example:
x = true y = 4 if (x) else 2 // y == 4 z = false y = y if (z) else 6 // y == 6
- Example:
- New: Number literals can now be written with underscores. For example
20_000_000.000_12
can be written instead of20000000.00012
. - New:
Array
values can now be compared against anotherarray
values (by comparing all the items in both arrays). - New:
Regex
values can be compared against otherRegex
values. Comparison returnstrue
if both regexes are exactly the same. - New: Brand-new
StandardExtension
providing general-purpose functions.assert(bool[, string])
: Throws error (with optional description as second argument) if thebool
is false. This is useful for tests.print(value)
: Prints the value if Primi is running in CLI.
- Improved: Optimized iterating over
String
value. - Fixed grammar
- Variable name 'return_whatever' was parsed as 'return' statement with the additional '_whatever' suffix - causing a syntax error. This is fixed now.
- It was not possible to place
//comments
inside array definition that spanned multiple lines. That's possible now.
- Primi now supports (and also requires) PHP 7.1.
Internals
- REPL: Do not cache AST when in REPL mode.
- Separate
::getStringValue()
and::getStringRepr()
methods for Value classes.- Idea behind this is similar to Python's
__str__
and__repr__
dunders. - Example for StringValue containing string
ahoj
:::getStringValue()
returnsahoj
.- This is what is printed when used with
print()
function.
- This is what is printed when used with
::getStringRepr()
return"ahoj"
(including the double quotes).- This is what
REPL
displays to the user as the expression's result.
- This is what
- Function's "string repr" now includes info whether it is a userland function or it represents a native PHP function.
- Idea behind this is similar to Python's
- Optimization: Text information in AST is now cached only for nodes that explicitly need it (using
NODE_NEEDS_TEXT
constant in handler class). - Optimization: Bunch of stuff that node handlers need to prepare before handling their AST node was moved from runtime to parsing time.
- Optimization:
NumberValue::isNumericInt()
helper method now simplified by usingctype_digit()
function. - Using newer version of
smuuf/php-peg
that has some new optimizations. - Refactoring and reworking tests:
- The examples in
examples
directory ARE the language tests. - Rewritten many tests and examples to use the new
assert()
function.
- The examples in
- New benchmark system:
- Two files that do roughly the same thing, one written in Primi and one written in PHP.
- Primi performance is now evaluated "how many times is Primi slower than an equivalent code in PHP?"
- This should make benchmarks more relevant - and any performance improvements or regressions should be more recognizable.
- Tests: Using GitHub Actions to run tests now (goodbye, Travis CI!).
Primi 0.3.2
-
New function:
array_has(key)
- Returns
true
if the array contains suchkey
. Returnsfalse
if not. - Examples:
a = [0: "a", 1: "b"]; a.has(0); // (bool) true a.has(1); // (bool) true a.has("nope"); // (bool) false
- Returns
-
New function:
array_get(key[, default])
- Returns a value having such
key
. If such key is missing, the expression returns some default value. - The default value is
null
by default, but it can be specified as the second argument. - Examples:
a = [0: "a", 1: "b"]; a.get(0); // (string) "a" a.get("hello"); // (null) a.get("hello_there", "yep"); // (string) "yep"
- Returns a value having such
-
Some tweaks to REPL visual design.
Primi 0.3.1.1
- Bugfix: Fixed
string_shuffle
function for unicode strings.
Primi 0.3.1
- REPL: Storing the latest result into "magic" underscore
_
variable_. - REPL: Avoid storing the same line into history multiple times if entered consecutively.
- REPL: Errors are now printed with color.
- REPL: Fixed bug in handling of multi-line input.
- Fixed bug of an internal
InternalUndefinedTruthnessException
error occasionally bubbling up to PHP itself.
Primi 0.3
- REPL mode is now a default behaviour of Primi's "primary binary"
./primi
if executed with zero arguments. - REPL now has a new command
??
which acts similarly to old?
command (prints all locally defined variables), but??
prints global variables, too (e.g. global functions coming from extensions). - The type
__function__
has been renamed to justfunction
. - New function:
string_join()
- Can be used to concatenate items from an array (and even nested arrays!).
- Example:
a = ",".join([1, 2, 3]); // (string) "1,2,3" b = ",".join([1, 2, ['nested', 'stuff'], 4]); // (string) "1,2,nested,stuff,4"
- New function:
string_shuffle()
- Returns a new string value containing shuffled string passed as input.
- Example:
a = "hello".shuffle(); // (string) "leloh" b = "hello".shuffle(); // (string) "ollhe" c = string_shuffle("hello"); // (string) "lheol" d = "123456789".to_string().shuffle(); // (string) "841376592"
- New function:
type()
- Returns the type of a value/variable as a string.
- Example:
a = type("hello"); // (string) "string" b = type(type); // (string) "function"
- Fixed bug in
hash_sha256
function for numbers.
Primi 0.2.5
- Truthness of
null
values can now be determined. That ultimately means that now it supports comparison to other truthy/untruthy values (such asbool
values, etc.) - REPL mode now has slightly better support for multiline input.
Primi 0.2.4
- NEW: Range definition literals
- Syntax:
left .. right
- Creates an array having integer values from
left
toright
using steps of (minus)1
.
- Creates an array having integer values from
left ..[step..] right
- Creates an array having values from
left
toright
using steps ofstep
.
- Creates an array having values from
- Only integer numbers and integer number variables can be used as boundaries for range/step definition. (Current implementation will coerce floats into integers.)
- Example:
The syntax is still experimental and may be subject to change.
r = 1 .. 5; // (array) [0: 1, 1: 2, 2: 3, 3: 4, 4: 5] r = 1 .. -2 // (array) [0: 1, 1: 0, 2: -1, 3: -2] a = 1; b = 5; r = a .. b // (array) [0: 1, 1: 2, 2: 3, 3: 4, 4: 5] r = 1 ..2.. 5; // (array) [0: 1, 1: 3, 2: 5] r = 1 ..4.. 7; // (array) [0: 1, 1: 5] r = 1 ..4.. 3; // ERR: Invalid step '4' for range
- Syntax:
- NEW: Added two hashing functions to Primi Standard Library.
hash_md5(string|number)
- Returns a string containing MD5 hash of string or number.
- Example:
"hello".hash_md5(); // (string) "5d41402abc4b2a76b9719d911017c592"
hash_sha256(string|number)
- Returns a string containing SHA256 hash of string or number.
- Example:
"hello".hash_sha256(); // (string) "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
- Minor optimizations and fixes.
Primi 0.2.3
- BC break: The
foreach..as
construct/syntax was dropped in favor of more readablefor..in
construct/syntax.. foreach (A as B) { ... }
becomesfor (B in A) { ... }
- New statements:
break
andcontinue
control statements that can be used to fine-tune execution flow when insidefor
orwhile
loops.- Their usage in global scope causes an error.
- BC break: Removed the
echo
statement, as it is undesirable by default (and by language's philosophy) for end-users to be able to perform any kind of direct output via Primi script.- One can still create an extension that provides such functionality via a new function.
Primi 0.2.2
- NEW: Logical operators.
- Implemented
and
,or
and proper!
negation operators.- Added helper Common::isTruthy() for having a single point of
truth for value's truthyness.
- Added helper Common::isTruthy() for having a single point of
- Precedence of operators is defined as follows (high to low):
(...)
!
*
,/
+
,-
==
,!=
,>=
,<=
,>
,<
and
or
- Implemented
- FIX: Fixed error in array_shuffle() function. …
- It did not operate on copy of the array. It does now.
- FIX: Fixed error when getting argument count for error message.
- Pretty major refactoring.
- Introduced left-to-right evaluation helpers.
- Supports short-circuiting.
- Introduced left-to-right comparion evaluation helper.
- Uses short-circuiting.
- Many places where we relied on PHP's internal boolean-evaluation logic
were now refactored to use ourCommon::isTruthy()
helper. - There was an attempt to normalize
number-bool
comparison.
- Introduced left-to-right evaluation helpers.
- Tests now support pragma comments, eg.
// pragma:one_liners
- This pragma (compilator/interpreter directive) forces the test runner to evaluate each line of the test as if it were standalone script.
- That enables us to test exceptions better (thrown Primi's error exception no longer terminates the whole test suite.)
- This leads to improved test coverage.
- This pragma (compilator/interpreter directive) forces the test runner to evaluate each line of the test as if it were standalone script.
Primi 0.2.1
- Handling of strings and numbers is now strict.
- No more magic conversion of
"123"
(string) to123
(number). - Comparison of string and integer is allowed, but always returns false.
- No more magic conversion of
- Regex literals are now
r"..."
instead of slashes. - REPL mode has new command
?
one can use to print out variables from global context.