-
Notifications
You must be signed in to change notification settings - Fork 3
Annotation Proposal
Annotations are values stored in chunks and function definitions accessed through the Closure
class. These allow for Metadata to be included in scripts. This is enabled only for C-Like mode.
Annotations for functions will be specified in code with @name value
, the name immediately following the @ symbol, and the value being a valid expression that can be evaluated at compile time. These include string literals, numbers, booleans, and tables with values consisting of those types.
To specify annotations for a chunk, use @@
instead of @
to attach it to the compile unit.
@@meta 1.0
@functionmeta "string"
@meta2 { hello: 'world' }
function hello()
{
}
This will add the annotation meta
with value 1.0
to the chunk, and the annotation functionmeta
with value "string"
to the hello()
function. meta2
on the function will contain a table with the data hello = world
Chunk-level annotations may also be specified as compiler directives. ScriptOptions will contain a directives property with a list of keywords. If a directive keyword is matched by the compiler, the following text will become the value of an annotation until either a semicolon or any whitespace is reached. This is stored as a string literal.
//Script Options
List<string> Directives { get; set; }
//Example
script.Options.Directives.Add("using");
DynValue v = script.LoadString("using A.B.C;");
Console.WriteLine(v.Closure.Annotations[0].Name); //"using"
Console.WriteLine(v.Closure.Annotations[0].Value); //"A.B.C"
ScriptOptions will contain an instance of IAnnotationPolicy
, an interface defined by:
public enum AnnotationResult
{
Allow,
Ignore,
Error
}
public interface IAnnotationPolicy
{
AnnotationResult OnChunkAnnotation(string name, string value);
AnnotationResult OnFunctionAnnotation(string name, string value);
}
OnChunkAnnotation
and OnFunctionAnnotation
control the compiler's behaviour when encountering an annotation. A result of Allow
will store the annotation in the bytecode, Ignore
will not store the annotation, and Error
will throw a compiler error.
Three default policies will be implemented, AnnotationPolicies.Allow
, AnnotationPolicies.Ignore
, AnnotationPolicies.Error
. These will store all annotations, ignore all annotations, or error on any annotation respectively. The default value will be set to Allow
.
Loading from bytecode will bypass the annotation policy as it only controls the compiler.
Add to Closure
class. Default initialised to Array.Empty<ClosureAnnotation>()
Use the LoadFile
/LoadString
/LoadStream
functions of script to get a DynValue containing the closure for the main script chunk.
public ClosureAnnotation[] Annotations { get; private set; }
public class ClosureAnnotation
{
public string Name { get; private set; }
public DynValue Value { get; private set; }
public ClosureAnnotation(string name, DynValue value)
{
Name = name;
Value = value
}
}
In the bytecode these annotations will be stored in a special Annot
instruction included immediately after Meta
. If there are no annotations, no Annot
opcode will be emitted.