plocarf
v1.1.0
Published
Program Language Of Classes And Restricted Functions
Downloads
2
Readme
PLOCARF (Programming Language Of Classes And Restricted Functions) is a
programming language that can be made restricted for some application and
then compiled into a JavaScript code (and later, possibly others too, even
with programs that don't use JavaScript).
This program is public domain.
=== Functions ===
.Error(message,[lineNumber])
A error subclass for PLOCARF compile errors. Instances of this class
will have properties "plocarfMessage" and "plocarfLineNumber" to give
information about the error.
.compatible(x,y,obj)
Tells if type x and y are compatible, if the value is type x, and the
expected type is type y. The third argument is an object whose "classes"
property is an object with the PLOCARF classes to use during checking.
.compile(txt,opt)
Compile a PLOCARF code given as the first argument. The second argument
should be an object with the properties:
.classes
An object whose keys are PLOCARF class names and the values are the
classes. Only own keys are used.
.constants
An object whose keys are constant names and whose values are the
values of those constant (which must be a signed 32-bit integer).
Only the own keys are used.
.functions
An object whose keys are PLOCARF global function names are the
functions. Only own keys are used.
.pool
An array of initial pool strings. New pool strings can be added,
which are given higher numbers than the strings in this pool. The
initial pool is empty if not given.
.traceFunction
If given, will be called when compilation begins with a version of
JavaScript's "Function" function (but of a different sandbox) and
the return value is expected to be a function that will return the
resulting function, in place of using Function to create it. You
may use this to add in your own compilation or to display the
JavaScript code that a PLOCARF function compiles into.
The output is an object with properties:
.classes
An object whose keys are names of PLOCARF classes and whose values
are those classes. The prototype is set to null.
.functions
An object whose keys are names of PLOCARF global functionss and
whose values are those functions (which you can call just like
JavaScript functions). The prototype is set to null.
.pool
The string pool (an array). This is a new array and does not modify
the string pool array given for the input.
.sandbox
The contextified sandbox object.
.makeClass(cname,inherits)
Make a non-root PLOCARF root class, with the given name and inheritance
(the "prototype" and "types" properties automatically inherit it). The
properties are the same as with .makeRootClass(), and the returned
function does nothing if called.
.makeFunction(type,fun,[redefinable])
Annotate a function fun with PLOCARF type information, and if
redefinable is true, allows PLOCARF code to redefine it. This adds two
properties named "type" and "redefinable" to the function. Return value
is the function itself.
.makeRootClass(cname,[fun])
Make a class suitable as a PLOCARF root class, with the given name (will
be given to a "cname" property). If the second argument is given, it
makes that function into a suitable PLOCARF root class; otherwise it
returns a new function that does nothing. The returned function also has
properties "inherits" (with value null), "prototype", and "types".
.makeUndefFunction(type)
Similar to .makeFunction but automatically makes it redefinable and it
throws an error if called. Must be redefined by the PLOCARF code.
.subset(x,y)
Tells if the permission set x (as a string of sorted characters) is a
(not necessarily strict) subset of the permission set y.
.typeEq(x,y)
Tells if two types are equal (a deep compare of arrays).
.typeEq2(x,y)
Tells if two types are equal, but considers an unrestricted numeric type
to be equal to a numeric type with a restricted range.
=== Classes ===
A PLOCARF class is represented as a JavaScript function with the following
properties:
.cname
The PLOCARF class name.
.inherits
The class it inherits from (null if it is a root class).
.locked
If exists and true, this class may not be subclassed. Subclasses of
existing subclasses are still possible if they aren't also locked.
.prototype
Has a "constructor" property which is this class itself, as well as
other properties for any PLOCARF methods and constants. These names
have a prefix: "F_" for methods, and "K_" for constants.
.sealed
If exists and true, no more properties may be added to this class.
Subclasses and properties in the subclasses are still possible.
.types
Has the same names as the properties of the prototype (except
constructor), but their values are types instead of defaults. In
addition to methods and constants there are also the types of
PLOCARF properties, which use a "P_" prefix. In the case of
properties, the types may optionally have a property named "note"
which is a index into the pool strings, and is the "note" that is
applied to this property.
Both the .prototype and .types properties have a full prototype chain
for all classes they inherit from, and the root has null prototype.
=== Data types ===
% ["%"]
Boolean. Represented as a JavaScript boolean.
+ ["+"]
Signed 32-bit integer. Represented as a JavaScript number.
n:n ["+",n,n]
Number within the given range (valid for properties and constants only).
Represented same as the + type.
^ ["^"]
Strings. Represented as a number which is an index into the string pool.
*t ["*",t]
List of values of type t. Represented as a JavaScript array of
representations of type t. PLOCARF lists are considered immutable and
JavaScript code should not alter their contents.
@c ["@",c]
Object of class c (or of any subclass). Represented as a JavaScript
object or null.
#c ["#",c]
Subclass of class c. Represented as the function returned by the
.makeClass() for that class.
&c ["&",c]
Subclass of class c and property values for it, except the properties
that belong to class c itself. Represented as a JavaScript object.
c t ["P",c,t]
Name of type t property or method of class c (or a superclass).
Represented as a string with the property or method name (including
the prefix, if any).
(z)t$x$ ["F",[z],t,x]
Function with arguments z with commas in between, each of which can be
a name and colon and type, or a type by itself; t is the return type,
and can be omitted if no return; x is the set of permissions, and $x$
can be omitted for a pure function. Represented as a function. The
array that represents the type specification does not include the names
of the arguments to the function, but does include the types. Note that
x in that array is a string, with the permissions in ASCII order.
!x ["!",x]
An opaque type. PLOCARF does nothing with values of such types except
passing them unchanged, and checking that the type is correct.
none ["."]
When a . expression is used to represent a null pointer, this is the
most general type of the expression; it becomes a @ type later. The
representation is null.
none ["?",f1,f2]
A type usable as a function argument or function return value (for
global functions only). See below section about custom function types.
none ["V"]
Only valid as the return type of a function. Indicates that there is no
return value (in JavaScript it is the undefined value, but this is not
guaranteed since a function that does return a value can be used too).
=== Custom function types ===
The type ["?",f1,f2] can be used as the type of arguments and/or return
value of host functions; this is like a kind of polymorphism. Cannot be
used in other cases such as a type of list elements or properties etc.
Arguments given to f1 (when annotating a function call):
- The annotated AST so far (an array; elements 2 and subsequent are the
arguments, where the "type" property of them are the annotated types;
element 1 is the AST for the expression evaluating to the function itself)
- The expected type of the return value
- The current index into the annotated AST array for this argument (will
be omitted if it is the return value)
The return value of f1 should be the type that this argument is expected
to be, or null if don't care, or a string if it is an error. It shouldn't
be null if it is the return value; it should be the actual return type.
Arguments given to f2 (when checking type compatibility):
- The function type to check compatibility with
- The argument or return type to check compatibility with
The return value of f2 should be true if it is OK or false otherwise.
If two function need compatible "?" types, then the array with the "?"
should be the same object (comparable by ===) in order to match.
=== Outer definitions ===
;
No effect. You can add semicolons between definitions to avoid any
ambiguity that may otherwise be involved. Adding multiple semicolons is
also OK.
x:y{z}
Make a new class named x which inherits from y and then z is the inner
definitions for that class.
x+{y}
Extend an existing class x with inner definitions y.
x y z
Define a global function, where x is the name, y is the type, and z is
the definition, which is one of: a {} statement, a semicolon by itself
(the resulting function throws an error if called, but it can be
redefined later with the same type; use this to forward declare), or a
equal sign followed by a expression.
x=y
Define a global constant/expression macro, named x, where y is an
expression that the x is replaced by when later used in a expression.
=== Inner definitions ===
;
No effect, like with outer definitions.
x{y}
Define a subclass of this class, named x, with inner definitions y.
x y z
Define a function as the class method; the syntax is same as that of a
global function definition. You can make a new definition in a subclass
but the definition in the subclass must have the same type.
x=:y
Define the type of a class constant x as type y. Subclasses inherit this
class constant with the same type.
x=y
Define the value of a class constant (must be a compile time constant
expression). Subclasses inherit this value by default but can redefine
it with a different value (but must have the same type).
x:y
Define the type of a property named x as type y. Subclasses will inherit
all property types. No value is defined, though. After any property list
expression involving this property is mentioned, it is then too late to
add further properties to any of those classes. After the type, you may
optionally add a quoted string, which is a "note".
=== Comments and preprocessor macros ===
Comments can be written by C style or C++ style (same as JavaScript).
=== Statements ===
=x
Return value x (for a function that does not return, use = by itself
with none afterward)
?x{y}
If x then y
?x{y}|{z}
If x then y else z
%x{y}
While x do y
<x>y{z}
For each element named x of y, do z (inside of the block z, x is a new
variable whose type is the type of elements of y)
<<
Continue
>>
Break
x:y=z
Declare variable named x of type y with initial value z
{x}
Make a compound statement. Variables are scoped inside of it
;
Do nothing (semicolons can be used to avoid ambiguity)
=== Expressions ===
A PLOCARF expression can be use the operators, but there is also the short
expressions which are one item, such as:
Numeric literal: Put a number which is decimal, or can be hexadecimal with
0x at front.
String literal: Make a pool string literal with quotation marks around it;
the syntax is otherwise JSON syntax of string literals.
List: Put [] with the items with commas in between.
Class name: Put # and the class name.
Null: Put . by itself for null object.
Variable or global function: You can use a name of a variable (including
arguments to the function) or a global function, to use its value.
=== Operators ===
x+y
Addition, or list concatenation
x-y
Subtraction; same as (x+(-y))
-y
Negative (must be a number)
x*y
Multiplication, or repeat list x, y times
x/y
Integer division
x%y
Remainder
!x
Logical not (convert to boolean if applicable)
x$:t
Type cast
x(y)
Call function x, or access element y of list x; see the function call
syntax section below
*x
Class of object or length of list
~x
Bitwise or boolean complement
x<<y
Shift left
x>>y
Shift y
x==y
Compare if equal (usable with numbers, classes, objects, booleans, pool
strings, and lists of any of these types)
x!=y
Compare if unequal (usable with same types as equal)
x<y
Compare if less (numbers only)
x>y
Compare if greater (numbers only)
x<=y
Compare if less or equal (numbers only)
x>=y
Compare if greater or equal (numbers only)
x&&y
Short-circuiting boolean and
x||y
Short-circuiting boolean or
x&y
Bitwise or boolean and
x|y
Bitwise or boolean or
x^y
Bitwise or boolean exclusive or
x=y
Assignment (you can also use a combined assignment operator with any of
+ - * / % << >> & | ^ operators with = after (with no space))
x?y:z
Conditional
x[y]
Make property list
(x,y)
Comma operator (the parentheses is require)
x.y
Use property or method or constant name y of class x (if a constant, it
is the value of the constant; otherwise it is the name)
x~y
Map list y with function x
=== Function call syntax ===
The x(y) expression syntax can actually be use for many kind of things,
which are as follows (based on the type of x) (the y is zero or more
arguments with commas in between):
Function
Call the function with the given arguments. The function has to be a
(not necessarily strict) subset of permissions of the function that
the call expression is in. If a function that does not return a value
is expected, you can always still use a function that does return a
value too, of any return type.
List
Access the given list element (zero-based). In this case (only), you
can have multiple arguments in case of nested lists (but this use of
multi arguments is optional). If the number is out of range, it is an
error (a JavaScript RangeError exception).
PropertyList
With one argument (a property name), read the value of that property
from the property list. Error if it is of the wrong class. With two
arguments, the second is the new value, and the result is the new
property list with that one property value changed.
MethodName
It needs one argument, which is a class name. The result is the
corresponding function from that class.
Class
Needs one or more arguments. The first is a method name, and the rest
are the arguments, and it calls it (subject to same restriction of
permissions as above).
Object
Similar to with a class, but the first argument to the function will
be omitted because instead the object itself is passed.