From 6bba9894d59a55fa94d19c81eb72e02c98659900 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:07:21 -0500 Subject: [PATCH 01/16] Removed const_definition Going to make constants a modifier for the variable symbol instead of their own keyword. --- ssc/sunscript.grammar | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ssc/sunscript.grammar b/ssc/sunscript.grammar index c32b51d..9cc582b 100644 --- a/ssc/sunscript.grammar +++ b/ssc/sunscript.grammar @@ -124,7 +124,6 @@ statement = statement_block; compound_statement = compound_statement_item {COMMA compound_statement_item}; compound_statement_item = - const_definition | variable_definition | variable_declaration | variable_assignment | @@ -170,10 +169,6 @@ term = unary_operator_list = unary_operator+; -// constants -const_definition = const_modifiers IDENTIFIER ASSIGN expression; -const_modifiers = CONST [LOCAL]; - // variables variable_reference = IDENTIFIER; // used in expressions variable_declaration = variable_modifiers IDENTIFIER; From 040091efcad641629b11060d1d7e131efc87b1a6 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:19:43 -0500 Subject: [PATCH 02/16] Removed node generation for constants --- ssc/parser.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ssc/parser.cs b/ssc/parser.cs index 38e9df8..a246f67 100644 --- a/ssc/parser.cs +++ b/ssc/parser.cs @@ -190,12 +190,6 @@ namespace arookas { case __sunConstants.VARIABLE_AUGMENT: return new sunNode(location); } - // constants - switch (id) { - case __sunConstants.CONST_DEFINITION: return new sunConstantDefinition(location); - case __sunConstants.CONST_MODIFIERS: return new sunNode(location); - } - // flow control switch (id) { case __sunConstants.IF_STATEMENT: return new sunIf(location); From 8db3326005ba415b78fa41937c8a92e49c01d61f Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:26:41 -0500 Subject: [PATCH 03/16] Made a modifiers switch block --- ssc/parser.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/ssc/parser.cs b/ssc/parser.cs index a246f67..0f85b01 100644 --- a/ssc/parser.cs +++ b/ssc/parser.cs @@ -205,17 +205,10 @@ namespace arookas { case __sunConstants.CONTINUE_STATEMENT: return new sunContinue(location); } - // keywords - if (id == __sunConstants.CONST) { - switch (parent) { - case __sunConstants.FUNCTION_MODIFIERS: - case __sunConstants.BUILTIN_MODIFIERS: { - return new sunConstKeyword(location); - } - } - } - if (id == __sunConstants.LOCAL) { - return new sunLocalKeyword(location); + // modifiers + switch (id) { + case __sunConstants.LOCAL: return new sunLocalKeyword(location); + case __sunConstants.CONST: return new sunConstKeyword(location); } // emergency fallback From e69d97478d240a597c919fc63eea3e06187b503b Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:27:30 -0500 Subject: [PATCH 04/16] Renamed keyword nodes to modifier nodes --- ssc/ast/nodes.keywords.cs | 8 ++++---- ssc/parser.cs | 4 ++-- ssc/symbol.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ssc/ast/nodes.keywords.cs b/ssc/ast/nodes.keywords.cs index fc85730..41698b1 100644 --- a/ssc/ast/nodes.keywords.cs +++ b/ssc/ast/nodes.keywords.cs @@ -1,11 +1,11 @@ namespace arookas { - class sunConstKeyword : sunNode { - public sunConstKeyword(sunSourceLocation location) + class sunConstModifier : sunNode { + public sunConstModifier(sunSourceLocation location) : base(location) { } } - class sunLocalKeyword : sunNode { - public sunLocalKeyword(sunSourceLocation location) + class sunLocalModifier : sunNode { + public sunLocalModifier(sunSourceLocation location) : base(location) { } } } diff --git a/ssc/parser.cs b/ssc/parser.cs index 0f85b01..b13f1cb 100644 --- a/ssc/parser.cs +++ b/ssc/parser.cs @@ -207,8 +207,8 @@ namespace arookas { // modifiers switch (id) { - case __sunConstants.LOCAL: return new sunLocalKeyword(location); - case __sunConstants.CONST: return new sunConstKeyword(location); + case __sunConstants.LOCAL: return new sunLocalModifier(location); + case __sunConstants.CONST: return new sunConstModifier(location); } // emergency fallback diff --git a/ssc/symbol.cs b/ssc/symbol.cs index a9de040..e1fb740 100644 --- a/ssc/symbol.cs +++ b/ssc/symbol.cs @@ -103,10 +103,10 @@ namespace arookas { return sunSymbolModifiers.None; } var modifiers = sunSymbolModifiers.None; - if (modifierlist.Any(i => i is sunConstKeyword)) { + if (modifierlist.Any(i => i is sunConstModifier)) { modifiers |= sunSymbolModifiers.Constant; } - if (modifierlist.Any(i => i is sunLocalKeyword)) { + if (modifierlist.Any(i => i is sunLocalModifier)) { modifiers |= sunSymbolModifiers.Local; } return modifiers; From 799b6e50935d7142f90904e19c0de0b663bd1cab Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:42:34 -0500 Subject: [PATCH 05/16] Removed unused constructor --- ssc/symbol.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/ssc/symbol.cs b/ssc/symbol.cs index e1fb740..685ab62 100644 --- a/ssc/symbol.cs +++ b/ssc/symbol.cs @@ -289,8 +289,6 @@ namespace arookas { get { return (uint)Index; } } - public sunVariableSymbol(string name) - : this(name, 0, 0) { } public sunVariableSymbol(string name, int display, int index) : base(name) { mDisplay = display; From 5163c94e3a527f8ff96fa85d541532a3b82b3960 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:43:44 -0500 Subject: [PATCH 06/16] Removed compiler parameter for relocations Since relocations are linked with the binary formatter directly, and each already does a keep/back restore, no point in doing that again when closing them. --- ssc/compiler.cs | 2 +- ssc/scope.cs | 4 ++-- ssc/symbol.cs | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ssc/compiler.cs b/ssc/compiler.cs index 8ff892d..5bc3dc7 100644 --- a/ssc/compiler.cs +++ b/ssc/compiler.cs @@ -131,7 +131,7 @@ namespace arookas { #endif void CompileRelocations() { foreach (var symbol in mContext.SymbolTable) { - symbol.CloseRelocations(this); + symbol.CloseRelocations(); } } void CompileData() { diff --git a/ssc/scope.cs b/ssc/scope.cs index 0c67263..11a5974 100644 --- a/ssc/scope.cs +++ b/ssc/scope.cs @@ -53,7 +53,7 @@ namespace arookas { mStack.Add(new sunScope(type)); } #endif - public void Pop(sunCompiler compiler) { + public void Pop() { if (Count > 1) { #if SSC_SCOPES if (Top.Type == sunScopeType.Script) { @@ -62,7 +62,7 @@ namespace arookas { #else // close relocations while we still have references to the symbols foreach (var variable in Top) { - variable.CloseRelocations(compiler); + variable.CloseRelocations(); } #endif mStack.RemoveAt(Count - 1); diff --git a/ssc/symbol.cs b/ssc/symbol.cs index 685ab62..72d678f 100644 --- a/ssc/symbol.cs +++ b/ssc/symbol.cs @@ -90,12 +90,10 @@ namespace arookas { } mRelocations.Add(relocation); } - public void CloseRelocations(sunCompiler compiler) { - compiler.Binary.Keep(); + public void CloseRelocations() { foreach (var relocation in mRelocations) { relocation.Relocate(); } - compiler.Binary.Back(); } public static sunSymbolModifiers GetModifiers(sunNode modifierlist) { @@ -202,7 +200,7 @@ namespace arookas { } mBody.Compile(compiler); compiler.Binary.WriteRET0(); - compiler.Context.Scopes.Pop(compiler); + compiler.Context.Scopes.Pop(); ++mCompiles; } public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) { From f3fc69c8703616e9c0da3de0196273096a39682b Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:45:30 -0500 Subject: [PATCH 07/16] Fixed: store modifiers in symbols --- ssc/ast/nodes.functions.cs | 6 ++++-- ssc/ast/nodes.variables.cs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ssc/ast/nodes.functions.cs b/ssc/ast/nodes.functions.cs index e0817e6..ad06105 100644 --- a/ssc/ast/nodes.functions.cs +++ b/ssc/ast/nodes.functions.cs @@ -14,7 +14,8 @@ namespace arookas { : base(location) { } public override void Compile(sunCompiler compiler) { - compiler.Context.DeclareBuiltin(this); + var symbol = compiler.Context.DeclareBuiltin(this); + symbol.Modifiers = Modifiers; } } @@ -33,7 +34,8 @@ namespace arookas { public override void Compile(sunCompiler compiler) { // this defines the function in the context // it doesn't compile the definition body - compiler.Context.DefineFunction(this); + var symbol = compiler.Context.DefineFunction(this); + symbol.Modifiers = Modifiers; } } diff --git a/ssc/ast/nodes.variables.cs b/ssc/ast/nodes.variables.cs index 3a4c6f8..d9cc8bb 100644 --- a/ssc/ast/nodes.variables.cs +++ b/ssc/ast/nodes.variables.cs @@ -32,7 +32,8 @@ : base(location) { } public override void Compile(sunCompiler compiler) { - compiler.Context.DeclareVariable(this); + var symbol = compiler.Context.DeclareVariable(this); + symbol.Modifiers = Modifiers; } } @@ -50,6 +51,7 @@ public override void Compile(sunCompiler compiler) { var symbol = compiler.Context.DeclareVariable(this); + symbol.Modifiers = Modifiers; Operator.Compile(compiler, symbol, Expression); } } From 6fe9de3af5cdea2ab57936a4ce17cf8a929cc2df Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:46:08 -0500 Subject: [PATCH 08/16] Added check against local builtins --- ssc/ast/nodes.functions.cs | 3 +++ ssc/exceptions.cs | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/ssc/ast/nodes.functions.cs b/ssc/ast/nodes.functions.cs index ad06105..be78dfb 100644 --- a/ssc/ast/nodes.functions.cs +++ b/ssc/ast/nodes.functions.cs @@ -16,6 +16,9 @@ namespace arookas { public override void Compile(sunCompiler compiler) { var symbol = compiler.Context.DeclareBuiltin(this); symbol.Modifiers = Modifiers; + if ((symbol.Modifiers & sunSymbolModifiers.Local) != 0) { + throw new sunInvalidModifierException(this[0]); // local builtins are not supported + } } } diff --git a/ssc/exceptions.cs b/ssc/exceptions.cs index 3c76c69..26b004e 100644 --- a/ssc/exceptions.cs +++ b/ssc/exceptions.cs @@ -251,4 +251,12 @@ namespace arookas { public sunContinueException(sunContinue node) : base(node) { } } + class sunInvalidModifierException : sunNodeException { + public override string Message { + get { return "Unsupported modifier in modifier list."; } + } + + public sunInvalidModifierException(sunNode node) + : base(node) { } + } } From d7ce89ca9a77a6b870cc607ef8128cf9569ea8fb Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:52:41 -0500 Subject: [PATCH 09/16] Added check against constant declarations --- ssc/ast/nodes.variables.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssc/ast/nodes.variables.cs b/ssc/ast/nodes.variables.cs index d9cc8bb..4d3cbd9 100644 --- a/ssc/ast/nodes.variables.cs +++ b/ssc/ast/nodes.variables.cs @@ -34,6 +34,9 @@ public override void Compile(sunCompiler compiler) { var symbol = compiler.Context.DeclareVariable(this); symbol.Modifiers = Modifiers; + if ((Modifiers & sunSymbolModifiers.Constant) != 0) { + throw new sunInvalidModifierException(this[0]); + } } } From a676f9e8e5db79d1f2465cfa581177b21c07b261 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 20:53:40 -0500 Subject: [PATCH 10/16] Merged sunConstDefinition and sunVariableDefinition Now sunVariableDefinition declares either a constant symbol or a variable symbol, depending on the appearance of the 'const' modifier. --- ssc/ast/nodes.variables.cs | 44 ++++++++++++++++---------------------- ssc/context.cs | 2 +- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/ssc/ast/nodes.variables.cs b/ssc/ast/nodes.variables.cs index 4d3cbd9..3c0596d 100644 --- a/ssc/ast/nodes.variables.cs +++ b/ssc/ast/nodes.variables.cs @@ -53,9 +53,24 @@ : base(location) { } public override void Compile(sunCompiler compiler) { - var symbol = compiler.Context.DeclareVariable(this); - symbol.Modifiers = Modifiers; - Operator.Compile(compiler, symbol, Expression); + // create the right type of symbol based on the const modifier + var isConst = (Modifiers & sunSymbolModifiers.Constant) != 0; + if (isConst) { + // analyze the expression. this does two things: + // 1) prevents recursion (i.e. the const referencing itself) + // 2) asserts actual constness + var flags = Expression.Analyze(compiler.Context); + if (flags.HasFlag(sunExpressionFlags.Dynamic)) { + throw new sunConstantExpressionException(Expression); + } + var symbol = compiler.Context.DeclareConstant(this); + symbol.Modifiers = Modifiers; + } + else { + var symbol = compiler.Context.DeclareVariable(this); + symbol.Modifiers = Modifiers; + Operator.Compile(compiler, symbol, Expression); + } } } @@ -75,27 +90,4 @@ Operator.Compile(compiler, symbol, Expression); } } - - class sunConstantDefinition : sunNode { - public sunIdentifier Name { get { return this[1] as sunIdentifier; } } - public sunExpression Expression { get { return this[3] as sunExpression; } } - - public sunSymbolModifiers Modifiers { - get { return sunSymbol.GetModifiers(this[0]) | sunSymbolModifiers.Constant; } - } - - public sunConstantDefinition(sunSourceLocation location) - : base(location) { } - - public override void Compile(sunCompiler compiler) { - // analyze the expression. this does two things: - // 1) prevents recursion (i.e. the const referencing itself) - // 2) asserts actual constness - var flags = Expression.Analyze(compiler.Context); - if (flags.HasFlag(sunExpressionFlags.Dynamic)) { - throw new sunConstantExpressionException(Expression); - } - compiler.Context.DeclareConstant(this); - } - } } diff --git a/ssc/context.cs b/ssc/context.cs index 63487ba..0eef991 100644 --- a/ssc/context.cs +++ b/ssc/context.cs @@ -111,7 +111,7 @@ namespace arookas { } return symbol; } - public sunConstantSymbol DeclareConstant(sunConstantDefinition node) { + public sunConstantSymbol DeclareConstant(sunVariableDefinition node) { return DeclareConstant(node.Name, node.Expression, node.Modifiers); } sunConstantSymbol DeclareConstant(sunIdentifier node, sunExpression expression, sunSymbolModifiers modifiers) { From 17157e177c4da3f55ac52ad08475c9ee6a3cfa29 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 21:04:13 -0500 Subject: [PATCH 11/16] Added const modifier to grammar --- ssc/sunscript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssc/sunscript.grammar b/ssc/sunscript.grammar index 9cc582b..32b70a6 100644 --- a/ssc/sunscript.grammar +++ b/ssc/sunscript.grammar @@ -173,7 +173,7 @@ unary_operator_list = unary_operator+; variable_reference = IDENTIFIER; // used in expressions variable_declaration = variable_modifiers IDENTIFIER; variable_definition = variable_modifiers IDENTIFIER ASSIGN expression; -variable_modifiers = VAR [LOCAL]; +variable_modifiers = VAR [LOCAL] [CONST]; variable_assignment = IDENTIFIER assignment_operator expression; variable_augment = postfix_augment | prefix_augment; From b7ec1a02735bcd95a59650900a9d4625aa4d6171 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 21:05:02 -0500 Subject: [PATCH 12/16] Updated const definitions --- stdlib/common.sun | 6 ++-- stdlib/sound.sun | 92 +++++++++++++++++++++++------------------------ stdlib/system.sun | 14 ++++---- stdlib/talk.sun | 12 +++---- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/stdlib/common.sun b/stdlib/common.sun index 7a62ee8..5e1a153 100644 --- a/stdlib/common.sun +++ b/stdlib/common.sun @@ -10,9 +10,9 @@ builtin const int(x); builtin const float(x); builtin const typeof(x); -const TYPE_INT = 0; -const TYPE_FLOAT = 1; -const TYPE_STRING = 2; +var const TYPE_INT = 0; +var const TYPE_FLOAT = 1; +var const TYPE_STRING = 2; // debug builtin dump(); diff --git a/stdlib/sound.sun b/stdlib/sound.sun index 2ae4539..9302590 100644 --- a/stdlib/sound.sun +++ b/stdlib/sound.sun @@ -15,49 +15,49 @@ builtin startMontemanBGM(); builtin startMontemanFanfare(); // [arookas] these are from mSound.asn -const MSD_BGM_DOLPIC = 0x80010001; -const MSD_BGM_BIANCO = 0x80010002; -const MSD_BGM_MAMMA = 0x80010003; -const MSD_BGM_PINNAPACO_SEA = 0x80010004; -const MSD_BGM_PINNAPACO = 0x80010005; -const MSD_BGM_MARE_SEA = 0x80010006; -const MSD_BGM_MONTEVILLAGE = 0x80010007; -const MSD_BGM_SHILENA = 0x80010008; -const MSD_BGM_RICCO = 0x80010009; -const MSD_BGM_GET_SHINE = 0x8001000A; -const MSD_BGM_CHUBOSS = 0x8001000B; -const MSD_BGM_MISS = 0x8001000C; -const MSD_BGM_BOSS = 0x8001000D; -const MSD_BGM_MAP_SELECT = 0x8001000E; -const MSD_BGM_BOSSPAKU_DEMO = 0x8001000F; -const MSD_BGM_MAIN_TITLE = 0x80010010; -const MSD_BGM_CHUBOSS2 = 0x80010011; -const MSD_BGM_EXTRA = 0x80010012; -const MSD_BGM_DELFINO = 0x80010013; -const MSD_BGM_MAREVILLAGE = 0x80010014; -const MSD_BGM_CORONA = 0x80010015; -const MSD_BGM_KAGEMARIO = 0x80010016; -const MSD_BGM_CAMERA = 0x80010017; -const MSD_BGM_MONTE_ONSEN = 0x80010018; -const MSD_BGM_MECHAKUPPA = 0x80010019; -const MSD_BGM_AIRPORT = 0x8001001A; -const MSD_BGM_UNDERGROUND = 0x8001001B; -const MSD_BGM_TITLEBACK = 0x8001001C; -const MSD_BGM_MONTE_NIGHT = 0x8001001D; -const MSD_BGM_CASINO = 0x8001001E; -const MSD_BGM_EVENT = 0x8001001F; -const MSD_BGM_TIME_IVENT = 0x80010020; -const MSD_BGM_SKY_AND_SEA = 0x80010021; -const MSD_BGM_MONTE_RESCUE = 0x80010022; -const MSD_BGM_MERRY_GO_ROUND = 0x80010023; -const MSD_BGM_SCENARIO_SELECT = 0x80010024; -const MSD_BGM_FANFARE_CASINO = 0x80010025; -const MSD_BGM_FANFARE_RACE = 0x80010026; -const MSD_BGM_CAMERA_KAGE = 0x80010027; -const MSD_BGM_GAMEOVER = 0x80010028; -const MSD_BGM_BOSSHANA_2ND3RD = 0x80010029; -const MSD_BGM_BOSSGESO_2DN3RD = 0x8001002A; -const MSD_BGM_CHUBOSS_MANTA = 0x8001002B; -const MSD_BGM_MONTE_LAST = 0x8001002C; -const MSD_BGM_SHINE_APPEAR = 0x8001002D; -const MSD_BGM_KUPPA = 0x8001002E; +var const MSD_BGM_DOLPIC = 0x80010001; +var const MSD_BGM_BIANCO = 0x80010002; +var const MSD_BGM_MAMMA = 0x80010003; +var const MSD_BGM_PINNAPACO_SEA = 0x80010004; +var const MSD_BGM_PINNAPACO = 0x80010005; +var const MSD_BGM_MARE_SEA = 0x80010006; +var const MSD_BGM_MONTEVILLAGE = 0x80010007; +var const MSD_BGM_SHILENA = 0x80010008; +var const MSD_BGM_RICCO = 0x80010009; +var const MSD_BGM_GET_SHINE = 0x8001000A; +var const MSD_BGM_CHUBOSS = 0x8001000B; +var const MSD_BGM_MISS = 0x8001000C; +var const MSD_BGM_BOSS = 0x8001000D; +var const MSD_BGM_MAP_SELECT = 0x8001000E; +var const MSD_BGM_BOSSPAKU_DEMO = 0x8001000F; +var const MSD_BGM_MAIN_TITLE = 0x80010010; +var const MSD_BGM_CHUBOSS2 = 0x80010011; +var const MSD_BGM_EXTRA = 0x80010012; +var const MSD_BGM_DELFINO = 0x80010013; +var const MSD_BGM_MAREVILLAGE = 0x80010014; +var const MSD_BGM_CORONA = 0x80010015; +var const MSD_BGM_KAGEMARIO = 0x80010016; +var const MSD_BGM_CAMERA = 0x80010017; +var const MSD_BGM_MONTE_ONSEN = 0x80010018; +var const MSD_BGM_MECHAKUPPA = 0x80010019; +var const MSD_BGM_AIRPORT = 0x8001001A; +var const MSD_BGM_UNDERGROUND = 0x8001001B; +var const MSD_BGM_TITLEBACK = 0x8001001C; +var const MSD_BGM_MONTE_NIGHT = 0x8001001D; +var const MSD_BGM_CASINO = 0x8001001E; +var const MSD_BGM_EVENT = 0x8001001F; +var const MSD_BGM_TIME_IVENT = 0x80010020; +var const MSD_BGM_SKY_AND_SEA = 0x80010021; +var const MSD_BGM_MONTE_RESCUE = 0x80010022; +var const MSD_BGM_MERRY_GO_ROUND = 0x80010023; +var const MSD_BGM_SCENARIO_SELECT = 0x80010024; +var const MSD_BGM_FANFARE_CASINO = 0x80010025; +var const MSD_BGM_FANFARE_RACE = 0x80010026; +var const MSD_BGM_CAMERA_KAGE = 0x80010027; +var const MSD_BGM_GAMEOVER = 0x80010028; +var const MSD_BGM_BOSSHANA_2ND3RD = 0x80010029; +var const MSD_BGM_BOSSGESO_2DN3RD = 0x8001002A; +var const MSD_BGM_CHUBOSS_MANTA = 0x8001002B; +var const MSD_BGM_MONTE_LAST = 0x8001002C; +var const MSD_BGM_SHINE_APPEAR = 0x8001002D; +var const MSD_BGM_KUPPA = 0x8001002E; diff --git a/stdlib/system.sun b/stdlib/system.sun index e93181f..37a5953 100644 --- a/stdlib/system.sun +++ b/stdlib/system.sun @@ -10,19 +10,19 @@ // ================================================= \\ // known flags here -const SYS_SHINEGET = 0x10000; // add shine num to this +var const SYS_SHINEGET = 0x10000; // add shine num to this -const SYS_MARIOLIVES = 0x20001; +var const SYS_MARIOLIVES = 0x20001; -const SYS_SHINENUM = 0x40000; -const SYS_BLUECOINNUM = 0x40001; -const SYS_GOLDCOINNUM = 0x40002; +var const SYS_SHINENUM = 0x40000; +var const SYS_BLUECOINNUM = 0x40001; +var const SYS_GOLDCOINNUM = 0x40002; builtin getSystemFlag(flag); builtin setSystemFlag(flag, value); -function setOnSystemFlag(flag) { setSystemFlag(flag, true); } -function setOffSystemFlag(flag) { setSystemFlag(flag, false); } +function setOnSystemFlag(flag) { setSystemFlag(flag, true); } +function setOffSystemFlag(flag) { setSystemFlag(flag, false); } // [arookas] custom utility function incSystemFlag(flag) { diff --git a/stdlib/talk.sun b/stdlib/talk.sun index 30f7724..1c18e0d 100644 --- a/stdlib/talk.sun +++ b/stdlib/talk.sun @@ -10,8 +10,8 @@ // ================================================= \\ // flags -const TALKF_WAIT = 0; -const TALKF_CLOSE = (1 << 0); +var const TALKF_WAIT = 0; +var const TALKF_CLOSE = (1 << 0); // builtins builtin getTalkMode(); @@ -62,8 +62,8 @@ function talk(msgID, flags) { } } -function talkAndWait(msgID) { talk(msgID, TALKF_WAIT); } -function talkAndClose(msgID) { talk(msgID, TALKF_CLOSE); } +function talkAndWait(msgID) { talk(msgID, TALKF_WAIT); } +function talkAndClose(msgID) { talk(msgID, TALKF_CLOSE); } // ================================================= \\ // SELECT @@ -89,8 +89,8 @@ function select(msgID, flags) { return getTalkSelectedValue(); } -function talkAndSelect(msgID) { return select(msgID, TALKF_WAIT); } -function talkAndSelectClose(msgID) { return select(msgID, TALKF_CLOSE); } +function talkAndSelect(msgID) { return select(msgID, TALKF_WAIT); } +function talkAndSelectClose(msgID) { return select(msgID, TALKF_CLOSE); } // ================================================= \\ // FORCE From 5575681124d59aed927dd2b6a13e2ccfaa6c7cfc Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 21:05:14 -0500 Subject: [PATCH 13/16] Reordered modifiers enum --- ssc/symbol.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssc/symbol.cs b/ssc/symbol.cs index 72d678f..9f1071e 100644 --- a/ssc/symbol.cs +++ b/ssc/symbol.cs @@ -345,7 +345,7 @@ namespace arookas { [Flags] enum sunSymbolModifiers { None = 0, - Constant = 1 << 0, - Local = 1 << 1, + Local = 1 << 0, + Constant = 1 << 1, } } From c56444d7ca23f128d6dca605846a2d5867c011a2 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 21:38:55 -0500 Subject: [PATCH 14/16] Renamed system-flag constants --- stdlib/system.sun | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/system.sun b/stdlib/system.sun index 37a5953..e7e7a32 100644 --- a/stdlib/system.sun +++ b/stdlib/system.sun @@ -10,13 +10,13 @@ // ================================================= \\ // known flags here -var const SYS_SHINEGET = 0x10000; // add shine num to this +var const SYSF_SHINEGET = 0x10000; // add shine num to this -var const SYS_MARIOLIVES = 0x20001; +var const SYSF_MARIOLIVES = 0x20001; -var const SYS_SHINENUM = 0x40000; -var const SYS_BLUECOINNUM = 0x40001; -var const SYS_GOLDCOINNUM = 0x40002; +var const SYSF_SHINENUM = 0x40000; +var const SYSF_BLUECOINNUM = 0x40001; +var const SYSF_GOLDCOINNUM = 0x40002; builtin getSystemFlag(flag); builtin setSystemFlag(flag, value); From 5e25a1aadafdba6218a82ea68f5d3478e3f55b4f Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 21:42:49 -0500 Subject: [PATCH 15/16] Refactored functions The decompiled versions were inconsistent. --- stdlib/system.sun | 10 ++-------- stdlib/talk.sun | 19 +++++++++---------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/stdlib/system.sun b/stdlib/system.sun index e7e7a32..35f445e 100644 --- a/stdlib/system.sun +++ b/stdlib/system.sun @@ -62,16 +62,10 @@ builtin startMareBottleDemo(); builtin isFinishMareBottleDemo(); function waitForFinishDemo() { - while (true) { - if (isDemoMode()) { - break; - } + while (!isDemoMode()) { yield; } - while (true) { - if (isDemoMode() == false) { - break; - } + while (isDemoMode()) { yield; } } diff --git a/stdlib/talk.sun b/stdlib/talk.sun index 1c18e0d..e857bbb 100644 --- a/stdlib/talk.sun +++ b/stdlib/talk.sun @@ -56,7 +56,7 @@ function talk(msgID, flags) { } else { yield; - while (getTalkMode() != true) { + while (!getTalkMode()) { yield; } } @@ -81,10 +81,9 @@ function select(msgID, flags) { } } else { - yield; - while (getTalkMode() != true) { + do { yield; - } + } while (!getTalkMode()); } return getTalkSelectedValue(); } @@ -103,20 +102,20 @@ builtin forceCloseTalk(); // functions function forceTalk(handle) { - var res = __forceStartTalk(handle); - if (res == true) { + var result = __forceStartTalk(handle); + if (result) { while (!isTalkModeNow()) { yield; } } - return res; + return result; } function forceTalkExceptNpc(handle) { - var res = __forceStartTalkExceptNpc(handle); - if (res == true) { + var result = __forceStartTalkExceptNpc(handle); + if (result) { while (!isTalkModeNow()) { yield; } } - return res; + return result; } From d88d113718359765ce25383825df9225e612bcac Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 22 Feb 2016 22:00:58 -0500 Subject: [PATCH 16/16] Updated language documentation --- language.md | 173 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 73 deletions(-) diff --git a/language.md b/language.md index 1616655..cb17bf0 100644 --- a/language.md +++ b/language.md @@ -11,62 +11,59 @@ Both single-line comments and multi-line comments are supported. A single line c A variable is created by use of the `var` keyword and may initially be either _declared_ or _defined_. A declaration leaves the variable with an undefined initial value, while a definition assigns a value to the variable explicitly: -```javascript +``` var a; var b = 33; ``` ---- - -There are three primitive types in SunScript, as shown in the following table. +There are several primitive types in SunScript, as shown in the following table. All variables are dynamically typed and can change at any time by simply assigning it an expression of another type. -|Type | Example| -|:-----|-------------:| -|int |`132`, `-0xff`| -|float |`15.64`, `9.0`| -|string| `"foo\nbar"`| +|Type|Example| +|:---|------:| +|int|`132`, `-0xff`| +|float|`15.64`, `9.0`| +|string |`"foo\nbar"`| +|address|`$803200A0`| -SunScript also has the two boolean keywords `true` and `false` (currently defined as the integers one and zero, respectively). +> **Note:** SunScript also has the two boolean keywords `true` and `false` (currently defined as the integers one and zero, respectively). ---- +#### Casting -To get the type of any variable or expression, use the `typeof` statement: +To explicitly cast to the integer and floating-point types, use the `int` and `float` casting statements: -```javascript +``` +var const PI = 3.14; +var piIsExactlyThree = int(PI); // *gasp* +``` +To get the type of any variable or expression, use the `typeof` statement. +Constants for the possible return values are defined in the [standard include library](stdlib/common.sun). + +``` var a = 1.1 * 8; var b = typeof(a); var c = typeof(1.1 * 8); // you may also put expressions as the argument ``` -Constants for the possible return values are defined in the [standard include library](stdlib/common.sun). - ---- - -To explicitly cast to the integer and floating-point types, use the `int` and `float` casting statements: - -```javascript -const PI = 3.14; -var piIsExactlyThree = int(PI); // *gasp* -``` - #### Constants -Read-only variables may be created via the `const` keyword. -Only constant definitions are allowed; constant declarations are **not** supported. +Read-only variables (constants) may be created via the `const` modifier. +They represent a special literal value which does not change. -To save space in the output binary, constants are not stored in the symbol table, nor are they compiled in the text section. -Instead, they are simply evaluated each time they are actually used (similar to macros in CPP): +> **Note:** A constant cannot be declared without a value. -```javascript -const PI = 3.14; -const TWOPI = 2 * PI; -const R = 300.0; +Constants are not stored in the symbol table, nor are their definitions compiled the text section. +Instead, they are simply compiled each time they are actually used (similar to macros in the C preprocessor): + +``` +var const PI = 3.14; +var const TWOPI = 2 * PI; +var const R = 300.0; var circ = R * TWOPI; // this actually compiles to 'var circ = 300.0 * (2 * (3.14));' ``` -_**Note:** You may assign only expressions which are evaluated to be constant._ +> **Note:** The expression assigned to a constant must be evaluated to be constant. A constant expression is one which contains only literals and constant symbols. ### Callables @@ -77,7 +74,7 @@ Callables may have any number of parameters. To define a function, use the `function` keyword. For builtins, use the `builtin` keyword: -```javascript +``` builtin getSystemFlag(flag); builtin setSystemFlag(flag, value); @@ -85,61 +82,62 @@ function setOnSystemFlag(flag) { setSystemFlag(flag, true); } function setOffSystemFlag(flag) { setSystemFlag(flag, false); } ``` -A callable may have any number of parameters. -Each parameter is dynamically typed. -A builtin may have a variadic signature by specifying an ellipsis keyword `...` as the final parameter (variadic functions are **not** supported): +Each of the callable's parameters is dynamically typed. +A builtin may have a variadic signature by specifying the ellipsis identifier `...` as the final parameter: -```javascript +``` builtin print(...); // variadic builtin print("Hello, ", "world!"); // this is legal print("I have ", 3, " arguments."); // so is this ``` +> **Note:** Variadic functions are _not_ supported. + A callable's return value is also dynamic. -Use a `return` statement to override the interpreter's default return value for a given code path. +Use a `return` statement to set the return value for a given code path. +Not all code paths are required to have a return value. --- Functions and builtins may be called either as standalone statements or in expressions. -To call a function or builtin, simply pass its name, followed by any arguments, each separated by a comma: +To call a function or builtin, simply pass its name, followed by any arguments in parentheses: -```javascript +``` appearReadyGo(); // calls the function 'appearReadyGo' with no arguments insertTimer(1, 0); // calls the function 'insertTimer' with two arguments, '1' and '0' ``` -_**Note:** You cannot call a function or builtin in code preceding its definition or declaration, respectively._ +> **Note:** You cannot call a builtin or function in code preceding its declaration or definition. ### Modifiers A declared symbol may be assigned compile-time modifiers. The modifiers follow their respective keywords in their declaration/definition: -```javascript -var foo; // global symbol (can be resolved from other scripts) -var local bar; // global symbol (can be resolved only from the current script) +``` +var foo; // global script symbol (can be resolved from other scripts) +var local bar; // local script symbol (can be resolved only from the current script) function local const getBaz() { return 132; } -const local baz = getBaz(); // getBaz is marked as constant +var local const baz = getBaz(); // getBaz is marked as constant ``` -_ssc_ supports the following modifiers: +SunScript supports the following modifiers: |Modifier|Description| |--------|-----------| |`local`|Resolves only within the current script file. Applies to only script-scope symbols.| -|`const`|Marks the symbol as constant. Allows for the symbol's use in `const` assignments.| +|`const`|Marks the symbol as constant. Allows for the symbol's use in constant expressions.| The following matrix details which symbol types support which modifiers: |type|`local`|`const`| |----|:-----:|:-----:| -|variable|✓| | -|constant|✓| | +|variable|✓|✓| |function|✓|✓| |builtin| |✓| @@ -165,34 +163,61 @@ The following table describes the operators supported by SunScript, as well as t ### Flow Control -SunScript has support for `while`, `do`, and `for` loops, as well as the `exit`, `break`, `continue`, and `return` statements: +Simple boolean flow control can be created using the `if` and `else` statements: -```javascript -function checkTime(time) { - if (time < 30) { - startMiss(); - exit; - } +``` +var coinNum = getSystemFlag(SYSF_GOLDCOINNUM); +if (coinNum >= needCoinNum) { + setSystemFlag(SYSF_GOLDCOINNUM, coinNum - needCoinNum); + startEventSE(1); + talkAndClose(0xD0019); + yield; + setNextStage(20, 0); } -var i = 0; -while (i < 100) { - checkTime(i); - if (stop) { - break; - } +else { + talkAndClose(0xD001A); } ``` +SunScript also supports the standard loop blocks `while`, `do`, and `for`: + +``` +var maniShineNum, var i; +for (i = 70; i < 86; ++i) { + if (isGetShine(i)) { + ++maniShineNum; + } +} +``` + +To stop execution of the script for the rest of the frame, use the `yield` statement. +Control will return on the next frame exactly where the script left off. + +``` +while(!isTalkModeNow()) { + yield; +} +``` + +To end execution of the script completely, use the `exit` statement: + +``` +if (getSystemFlag(SYSF_MARIOLIVES) > 5) { + exit; +} +startMiss(); +``` + #### Named Loops -Loops may be named. +Loops may be named in order to reference them from within nested loops. To name a loop, simply prefix the loop with a label. `break` and `continue` statements may be passed the name of the loop which they affect: -```javascript +``` outer_loop: -for (var a; a < 4; ++a) { - for (var b; b < 4; ++b) { +for (var a = 0; a < 4; ++a) { + for (var b = 0; b < 4; ++b) { if (b == 2) break outer_loop; } } @@ -204,22 +229,24 @@ You may split a script amongst several files. Doing this requires the use of the `import` statement. Simply pass the name of the SunScript file to import: -```javascript +``` +import "ssc/common.sun"; import "constants.sun"; import "C:/math.sun"; ``` -_**Note:** It is recommended to avoid using backslashes, as they may be interpreted as an escape._ +> **Note:** It is recommended to avoid using backslashes, as they may be interpreted as an escape. Importing files is managed by the `sunImportResolver` instance passed to the compiler. -The resolver can be the default (`sunImportResolver.Default`) or a completely custom one. +The resolver can be the default (returned by the `sunImportResolver.Default` property) or a completely custom one. If an import resolver fails to find a file, a compiler error will occur. --- -The default import resolver, `sunImportResolver.Default`, imports scripts by searching and loading files from disk. Where the resolver looks for the script depends on whether the given name is _absolute_ or _relative_: +The default import resolver imports scripts by searching and loading files from disk. Where the resolver looks for the script depends on whether the given name is _absolute_ or _relative_: -- If the name is _relative_, then the resolver will first append the name to the directory of the current file. If the script then is not found there, it will then look for the script in the compiler's executable directory. +- If the name is _relative_, then the resolver will look relative to the directory of the current file, followed by the compiler's executable directory. - If the name is _absolute_, then the resolver will simply look for the script only in the path specified. -The resolver also keeps track of all files that have been imported and will skip over files whose contents have already been compiled (in order to prevent recursion). +It also keeps track of all files that have been imported and will skip over files whose contents have already been compiled. +This helps prevent infinite recursion.