Skip to content

smack0007/Snowflake

Repository files navigation

The MIT License Build Status

Snowflake

Snowflake is a scripting language implemented in C#. The following is an example Snowflake script:

func buildMultiplier(x) {
	return func(y) {
		return x * y;
	};
}

var x5 = buildMultiplier(5);

for (var i = 0; i < 10; i += 1) {
	print("5 * " + i + " = " + x5(i));
}

var values = [ 1, 2, 3, 4, 5 ];
print(values.Count);

Interop

Snowflake scripts by default do not have access to any .NET BCL classes or methods besides those types which are baked into the language. Access can be given to scripts if necessary by setting global variables inside the ScriptEngine:

engine.SetGlobalFunction<object>("print", (x) => Console.WriteLine(x));

In order to allow objects to be available in your script, you'll need to register the objects with the ScriptEngine:

engine.RegisterType("MyApp.Person", typeof(Person));

Once the ScriptEngine has access to the type, your scripts can create objects like so:

var person = new MyApp.Person();
person.FirstName = "Bob";
person.LastName = "Freeman";
person.Age = 42;

Static objects can also be accessed this way:

engine.RegisterType("System.Console", typeof(Console));

In your script:

System.Console.WriteLine("Hello World!");

Language Structure

The following is the structure of the language following the EBNF language as closely as possible:

Script = <Statement>* EOF ;

StatementBlock = "{" <Statement>* "}" ;

Statement = <ConstDeclaration> ";" |
            <VariableDeclaration> ";" |
            <FunctionDeclaration> |
			<If> |
			<While> |
			<For> |
			<ForEach> |
			<Return> |
			<Expression> ";" ;

ConstDeclaration = "const" <Identifier> "=" <Expression> ;

VariableDeclaration = "var" <Identifier> ( "=" <Expression> )? ;

FunctionDeclaration = "func" <Identifier> "(" <FunctionParameters>  ")" <StatementBlock> ;

FunctionParameters = <Identifier>? ( "," <Identifier> )* ;

If = "if" "(" <Expression> ")" <StatementBlock> { "else" <StatementBlock> } ;

While = "while" "(" <Expression> ")" <StatementBlock> ;

For = "for" "(" ( <VariableDeclaration> | <Assignment> ) ";" <Expression> ";" <Assignment>  ")" <StatementBlock> ;

ForEach = "foreach" "(" <VariableDeclaration> "in" <Expression>  ")" <StatementBlock> ;

Return = "return" <Expression> ";" ;

Expression = <AssignmentExpression> ;

AssignmentExpression = <ConditionalOrExpression> | <Assignment> ;

ConditionalOrExpression = <ConditionalAndExpression> ( "||" <ConditionalAndExpression> )* ;

ConditionalAndExpression = <EqualityExpression> ( "&&" <EqualityExpression> )* ;

EqualityExpression = <RelationalExpression> ( ( "==" | "!=" ) <RelationalExpression> )* ;

RelationalExpression = <AdditiveExpression> ( ( "<" | "<=" | ">" | ">=" ) <AdditiveExpression> )* ;

AdditiveExpression = <MultiplicativeExpression> ( ( "+" | "-" ) <MultiplicativeExpression> )* ;

MultiplicativeExpression = <UnaryExpression> ( ( "*" | "/" ) <UnaryExpression> )* ;

UnaryExpression = ( ( "-" | "!" ) <UnaryExpression> )* | <PrimaryExpression> ;

PrimaryExpression = "(" <Expression> ")" |
					<AnonymousFunction> |
					<ConstructorCall> |
					<FunctionCall> |
					<List> |
					<Array> |
					<Dictionary> |
					<MemberAccess> |
					<PostfixOperation> |
					<Identifier> |
					<Value> ;

Assignment = <AssignmentTarget> <AssignmentOperation> <Expression> ;

AssignmentTarget = <Identifier> | <MemberAccess> ;

AssignmentOperation = "=" | "+=" | "-=" | "*=" | "/=" ;

AnonymousFunction = "func" "(" <FunctionParameters> ")" <StatementBlock> ;

FunctionCall = <Expression> "(" ( <Expression> ("," <Expression>)* )? ")" ;

ConstructorCall = "new" <TypeName> "(" ( <Expression> ("," <Expression>)* )? ")" ;

TypeName = <Identifier> ( "." <Identifier> )* ( "<" <TypeName> ( "," <TypeName> )* ">" )? ;

List = "[" <Expression>? ( "," <Expression> )* "]" ;

Array = "[|" <Expression>? ( "," <Expression> )* "|]" ;

Dictionary = "{" <DictionaryPair>? ( "," <DictionaryPair> )* "}" ;

DictionaryPair = ( <Identifier> | <Expression> ) ":" <Expression> ;

MemberAccess = <Expression> "." <Identifier> ( "(" ( <Expression> ( "," <Expression> )* )? ")" )? ;

PostfixOperation = <Expression> ( "++" | "--" ) ;

ElementAccess = <Expression> "[" <Expression> "]" ;

Identifier = [A-Za-z_][A-Za-z0-9_]* ;

Value = <Null> | <Boolean> | <String> | <Char> | <Integer> | <Float> ;

Null = "null" ;

Boolean = "true" | "false" ;

String = "\"" <chars>* "\"" ;

Integer = [1-9]* ;

Float = [1-9]*[.][1-9]* ;

About

Scripting language which compiles to C# and then to IL code using Roslyn.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages