packages feed

sifflet-2.3.0: datafiles/siffml-2.0.rnc

# -*- mode: conf -*-
# schema for siffml-2.0.
# RELAX NG compact syntax, using a grammar
#
# All valid siffml-1.0 documents are also valid as siffml-2.0,
# as the only change is the addition of FunctionType as
# another alternative in SiffletType

start = Functions

# Functions and children

Functions = element functions { CompoundFunction* }
CompoundFunction = 
    element compound-function { Name, ReturnType, ArgTypes, ArgNames, Body }
Name = element name { text }
ReturnType = element return-type { SiffletType }
ArgTypes = element arg-types { SiffletType* }
ArgNames = element arg-names { Name* }
Body = element body { SiffletExpr }

# Types (variants of VpType)

SiffletType = 
    StringType | CharType | NumType | BoolType | ListType | 
    FunctionType | TypeVariable

StringType = element string-type { empty }
CharType = element char-type { empty }
NumType = element num-type { empty }
BoolType = element bool-type { empty }
ListType = element list-type { SiffletType }

FunctionType = element function-type { 
                   SiffletType, # argument type
                   SiffletType # return type (which may be a function type)
               }

TypeVariable = element type-variable { text }

# Expressions (variants of Expr)
#    Expr also has a EList constructor, but this is not used in SiffML

SiffletExpr = Undefined | Symbol | Literal | If | Call

Undefined = element undefined { empty }
Symbol = element symbol { text }
Literal = element literal { SiffletValue }
If = element if { SiffletExpr, SiffletExpr, SiffletExpr }
Call = element call { Symbol, SiffletExpr* }

# A "list" element as an expr is probably a mistake.
# List = element list { SiffletExpr }

# Values (variants of Value)

SiffletValue = TRUE | FALSE | Char | String | Int | Float | List | Function

TRUE = element True { empty }
FALSE = element False { empty }
Char = element char { text }
String = element string { text }
Int = element int { text }
Float = element float { text }

# A "list" element represents a list value, not a list expr.
List = element list { SiffletValue* }

# Function values shouldn't happen, but just in case:
Function = element function { CompoundFunction }