-
Notifications
You must be signed in to change notification settings - Fork 1
Syntax
Expression grammar is defined in ast.h:
// WendyScript Syntax Grammar is defined as follows:
// expression_list -> assignment | assignment "," expression_list
// expression -> assignment
// assignment -> or (("=" | "=>" | "+=" | "-=" | "*=" | "/=" | "\=") or)*
// or -> and (("or") and)*
// and -> comparison (("and") comparison))*
// comparison -> range (("in" | "!=" | "==" | "<" | ">"
// | "<=" | ">=" | "~") range)*
// range -> comparison (("->") comparison)*
// term -> factor (("-" | "+") factor)*
// factor -> unary (("*" | "/" | "\" | "%") unary)*
// unary -> ("-" | "!" | "~") unary | member
// member -> array "." member | array
// array -> function_call | function_call ("[" expression "]")*
// function_call -> primary | primary ("(" expression_list ")")*
// primary -> NUMBER | STRING | TRUE | FALSE | NONE | IDENTIFIER |
// "(" expression ")" | "[" expression_list "]" |
// "#:" "(" identifier_list ")" "{" statement_list "}"
// Inspired by https://lambda.uta.edu/cse5317/notes/node26.html
Grammar is parsed via a right-recursive descent parser into an abstract syntax tree.
ast.c shows the different types of expressions.
-
Literal Expression (Primary Expression)
"Hello" // String Literal 10.23 // Number Literal true | false | none // Keyword Literal identifier // Identifier Literal [ PRIMARY, ... ] // List Literal (generates a List Expression) ( EXPRESSION ) // Parenthesized Expression #: (IDENTIFIER, ...) STATEMENT // Lambda Literal (generates a Function Expression) -
Binary Expression
-
Unary Expression
-
Call Expression
Function call in the form of
IDENTIFIER(arg, ...). -
List Expression
Generated from a List Literal
-
Function Expression
Either generated from a Lambda Literal or from a function identifier bind:
let fn => (IDENTIFIER, ...) STATEMENT // which is equivalent to let fn = #:(IDENTIFIER, ...) STATEMENT
Statements can be classified into three primary groups:
-
Expression Statements
These are simply expressions that sit on the top level of the code, which will be printed to the screen.
"Hello World!" // will print to the screen -
Block Statements
A list of statements can be used in place of a single STATEMENT by wrapping them in curly braces:
{ STATEMENT STATEMENT STATEMENT }Semicolons are optional and the primary source file is parsed by default as a list of statements.
-
Control Flow Statements
parse_statement() in ast.c shows the different statements and their syntax.
-
LET Statement
Binds an expression to an identifier.
let IDENTIFIER = EXPRESSION let IDENTIFIER => (IDENTIFIER, ...) STATEMENT -
IF Statement
Conditionally runs a block of code.
if EXPRESSION STATEMENT if EXPRESSION STATEMENT else STATEMENT -
FOR Statement
for EXPRESSION STATEMENTExecutes
STATEMENTas long asEXPRESSIONreturnstrue.for IDENTIFIER:EXPRESSION STATEMENTDeclares the
IDENTIFIER. Iterates through EXPRESSION (which must be a List, String, or Range), setsIDENTIFIERto each element of the collection before executingSTATEMENTand stops when each element of the collection has been visited. Modifying the collection during the loop may cause undefined behaviour. -
STRUCT Statement
Defines a Structure to create Objects
struct IDENTIFIER => (INSTANCE_MEMBER, ...) [STATIC_MEMBER, ...] -
INC Statement
Increments a Number variable by 1.
inc IDENTIFIER -
DEC Statement
Decrements a Number variable by 1.
dec IDENTIFIER -
INPUT Statement
Prompts for user input and stores the inputted value in the given variable. If the input can be parsed as a Number, it will be stored as such, otherwise a String.
input IDENTIFIER -
@ Statement
Prints the next expression but without appending a NEWLINE character.
@EXPRESSION -
RET Statement
Returns a value to the caller of the function.
ret EXPRESSION