Skip to content

Annotation Proposal

Callum edited this page Apr 6, 2022 · 4 revisions

Annotations

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.

Writing Annotations

Annotations for chunks will be specified in code with @name value, the name immediately following the @ symbol, and the value being the rest of the source line after the first encountered whitespace.

Annotations for functions will be similar, but be specified with @@ at the start of the line. These annotations will be stored with the next function definition. It will be illegal to have @@ hanging at the end of a source file, this will throw a compiler error.

@meta one

@@functionmeta two words
function hello()
{

}

This will add the annotation meta:one to the chunk, and the annotation functionmeta:two words to the hello() function.

Directives

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 a new line is reached.

//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"

Enabling Annotations

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.

Accessing Annotations

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 string Value { get; private set; }
    
    public ClosureAnnotation(string name, string 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.

Clone this wiki locally