Dragon banner

Dragon & Fox
Collective

Fox banner

Update

Published by Jady on 7/5/24, 2:15 PM

Update on what I've been doing: I went back to working on the game engine and I've been making a lot of progress. My current goal is to have every part of the editor editable in the editor, which, by the time that gets done, should mean it's fully possible to make games in it :D

TLDR I've gone from having a code-centered workspace with an editor on top of it, to having the code in the editor, which allows for way more flexibility and cuts down on all the tedious boilerplate I was having to write, which was part of the reason why I wanted to write my own programming language in the first place. So now I'm just faking it til I make it :3

the baby code is you

Published by Jady on 6/12/24, 7:09 PM

my roommates keep telling me i'm programming baby code in ms paint, when i'm doing stuff like th is

Another helpful tip

Published by Jady on 6/5/24, 10:23 PM

Friendly reminder to cut your losses! I could spend an extra two weeks rewriting part of the Cetus compiler to be all sorts of safe, at the cost of my sanity. Or, since I know I'm gonna be rewriting the whole thing in Cetus in a while anyway, which is way easier to do these certain things in, I can just wait it out. So, no spamming generic classes everywhere.

Fewer syntax definitions

Published by Jady on 5/23/24, 11:36 PM

I've narrowed down all the syntax definitions to just a few lines of really flexible code:


IToken fieldToken = new TokenString([new ParameterValueToken("fieldTypes"), new ParameterValueToken("fieldNames")]);
IToken parameterToken = new TokenString([new ParameterValueToken("parameterTypes"), new ParameterValueToken("parameterNames")]);
IToken varArgParameterToken = new TokenString([new ParameterValueToken("varArgParameterType"), new LiteralToken("..."), new ParameterValueToken("varArgParameterName")]);
AddFunction(ContextType.Program, Functions.Program, 100, new TokenSplit(new PassToken(), new LiteralToken(";"), new EOFToken(), new ParameterExpressionToken("statements")));
AddFunction(ContextType.Program, Functions.Struct, 90, new TokenString([new ParameterValueToken("name"), new TokenSplit(new LiteralToken("{"), new LiteralToken(";"), new  LiteralToken("}"), new TokenOptions([fieldToken, new ParameterExpressionToken("functions")]))]));
AddFunction(ContextType.Program, Functions.Function, 80, new TokenString([new ParameterValueToken("returnType"), new ParameterValueToken("name"), new TokenSplit(new LiteralToken("("), new LiteralToken(","), new LiteralToken(")"), new TokenOptions([parameterToken, varArgParameterToken])), new TokenOptional(new TokenSplit(new LiteralToken("{"), new LiteralToken(";"), new LiteralToken("}"), new ParameterExpressionToken("statements")))]));

AddFunction(ContextType.Function, Functions.Declare, 100, new TokenString([new LiteralToken("Declare"), new ParameterValueToken("type"), new ParameterValueToken("name")]));
AddFunction(ContextType.Function, Functions.Define, 100, new TokenString([new ParameterValueToken("type"), new ParameterValueToken("name"), new LiteralToken("="), new ParameterExpressionToken("value")]));
AddFunction(ContextType.Function, Functions.Assign, 100, new TokenString([new ParameterExpressionToken("target"), new LiteralToken("="), new ParameterExpressionToken("value")]));
AddFunction(ContextType.Function, Functions.Return, 100, new TokenString([new LiteralToken("Return"), new TokenOptional(new ParameterExpressionToken("value"))]));
AddFunction(ContextType.Function, Functions.Add, 30, new TokenString([new ParameterExpressionToken("a"), new LiteralToken("+"), new ParameterExpressionToken("b")]));
AddFunction(ContextType.Function, Functions.LessThan, 40, new TokenString([new ParameterExpressionToken("a"), new LiteralToken("<"), new ParameterExpressionToken("b")]));
AddFunction(ContextType.Function, Functions.While, 100, new TokenString([new LiteralToken("While"), new LiteralToken("("), new ParameterExpressionToken("condition"), new LiteralToken(")"), new ParameterExpressionToken("body")]));

More functions

Published by Jady on 5/22/24, 10:57 PM

Here's a more in-depth diagram of how the compiler works, if you can understand stuff like regex:


// Source code

extern Void printf(String format, Int... values);

Foo
{
	Int a;
	Int b;
	
	Foo New(Int a, Int b)
	{
		Declare Foo this;
		this.a = a;
		this.b = b;
		Return this;
	}
	
	Int* A(Foo this)
	{
		Return this.a;
	}
};

Void main()
{
	Foo foo = Foo.New(2, 3);
	printf("Starting at %i\n", foo.A());
	
	While (foo.A() < 6)
	{
		foo.A() = foo.A() + 1;
		printf("Loop %i\n", foo.A());
	};
	
	printf("Ending at %i\n", foo.A());
	Return;
};

// Compiler first pass
// Mostly just grab all the type and function information

// Available functions
Parameter(String type, String name)
	as "$type $name";
VarArgParameter(String type, String name)
	as "$type... $name";
Body(Int index)
	as "\{ $index=lexer.Index \}";
Function(String name, Parameter[] parameters, VarArgParameter? varArgParameter, String returnType, Body? body)
	as "$returnType $name \(\) $body"
	as "$returnType $name \( $varArgParameter (,)? \) $body"
	as "$returnType $name \( $parameters (, $parameters)* (, $varArgParameter)? (,)? \) $body";
Field(String type, String name)
	as "$type $name";
Struct(String name, Field[] fields, Function[] functions)
	as "$name \{ ($fields | $functions)+ \}";
Program(Struct[] structs, Function[] functions)
	as "($structs | $functions)+";



Program(
[
	Struct("Foo", [Field("Int", "a"), Field("Int", "b")],
		[
			Function("New", [Parameter("Int", "a"), Parameter("Int", "b")], None, "Foo", Some(FOO.NEW BODY INDEX)),
			Function("A", [Parameter("Foo", "this")], None, "Int*", Some(FOO.A BODY INDEX),
		]),
],
[
	Function("printf", [Parameter("String", "format")], Some(Parameter("Int", "values")), "Void", None),
	Function("main", [], None, "Void", Some(MAIN BODY INDEX)),
]);

// Compiler second pass
// Generate any intermediary code needed to parse function bodies

// Available functions
Parameter(Type type, String name);
Body(Int index);
Function(String name, Parameter[] parameters, Parameter? varArgParameter, String returnType, Body? body);
Field(Type type, String name);
Struct(String name, Field[] fields, Function[] functions);
Program(Struct[] structs, Function[] functions);



Program(
[
	Struct("Foo", [Field(Int, "a"), Field(Int, "b")],
		[
			Function("New", [Parameter(Int, "a"), Parameter(Int, "b")], None, Foo, Some(FOO.NEW BODY INDEX)),
			Function("A", [Parameter(Foo, "this")], None, Int*, Some(FOO.A BODY INDEX),
			Function("Get_a", [Parameter(Foo, "this")], None, Int*, None),
			Function("Get_b", [Parameter(Foo, "this")], None, Int*, None),
		]),
],
[
	Function("printf", [Parameter(String, "format")], Some(Parameter(Int, "values")), Void, None),
	Function("main", [], None, Void, Some(MAIN BODY INDEX)),
	Function("Get_Foo.New", [Parameter(Type<Foo>, "type")], None, Foo.New, None),
	Function("Get_Foo.A", [Parameter(Type<Foo>, "type")], None, Foo.A, None),
	Function("Call_Foo.A", [Parameter(Foo, "this")], None, () => Foo.A(this), None),
]);

// Compiler third pass
// Now we get to the actual function definitions

// Available functions

/// Compiler functions
Define(Type type, String name, Value value)
	as "$type $name = $value";
Declare(Type type, String name)
	as "$type $name";
Assign(Value target, Value value)
	as "$target = $value";
Return(Value? value)
	as "Return $value?";
While(Expression condition, Expression body)
	as "While ( $condition ) $body";
LessThan(Value left, Value right)
	as "$left < $right";
Add(Value left, Value right)
	as "$left + $right";

/// User functions
printf(String format, Value... values);
main();

/// Compiler-generated user functions
Foo.Get_a(Foo this)
	as "$this.a";
Foo.Get_b(Foo this)
	as "$this.b";
Get_Foo.New(Type type)
	as "$type.New";
Get_Foo.A(Type type)
	as "$type.A";
Call_Foo.A(Foo this)
	as "$this.A";



Foo.New(Int a, Int b)
{
	Declare(Foo, "this");
	Assign(Foo.Get_a(this), a);
	Assign(Foo.Get_b(this), b);
	Return(Some(this));
}

Foo.A(Foo this)
{
	Return(Foo.Get_a(this));
}

Main()
{
	Define(Foo, "foo", Get_Foo.New(Foo)(2, 3));
	printf("Starting at %i", Call_Foo.A(foo)());
	
	While(LessThan(Call_Foo.A(foo)(), 6),
	{
		Assign(Call_Foo.A(foo)(), Add(Call_Foo.A(foo)(), 1));
		printf("Loop %i", Call_Foo.A(foo)());
	});
	
	printf("Ending at %i", Call_Foo.A(foo));
	Return(None);
}

Everything is functions. Even the functions.