Merge pull request #1 from arookas/dev

Overhaul of constants
This commit is contained in:
arookas 2016-02-22 22:09:01 -05:00
commit 25702d2c79
15 changed files with 230 additions and 222 deletions

View file

@ -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 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: A declaration leaves the variable with an undefined initial value, while a definition assigns a value to the variable explicitly:
```javascript ```
var a; var a;
var b = 33; var b = 33;
``` ```
--- There are several primitive types in SunScript, as shown in the following table.
There are three 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. All variables are dynamically typed and can change at any time by simply assigning it an expression of another type.
|Type | Example| |Type|Example|
|:-----|-------------:| |:---|------:|
|int |`132`, `-0xff`| |int|`132`, `-0xff`|
|float |`15.64`, `9.0`| |float|`15.64`, `9.0`|
|string| `"foo\nbar"`| |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 a = 1.1 * 8;
var b = typeof(a); var b = typeof(a);
var c = typeof(1.1 * 8); // you may also put expressions as the argument 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 #### Constants
Read-only variables may be created via the `const` keyword. Read-only variables (constants) may be created via the `const` modifier.
Only constant definitions are allowed; constant declarations are **not** supported. 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. > **Note:** A constant cannot be declared without a value.
Instead, they are simply evaluated each time they are actually used (similar to macros in CPP):
```javascript Constants are not stored in the symbol table, nor are their definitions compiled the text section.
const PI = 3.14; Instead, they are simply compiled each time they are actually used (similar to macros in the C preprocessor):
const TWOPI = 2 * PI;
const R = 300.0; ```
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));' 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 ### Callables
@ -77,7 +74,7 @@ Callables may have any number of parameters.
To define a function, use the `function` keyword. To define a function, use the `function` keyword.
For builtins, use the `builtin` keyword: For builtins, use the `builtin` keyword:
```javascript ```
builtin getSystemFlag(flag); builtin getSystemFlag(flag);
builtin setSystemFlag(flag, value); builtin setSystemFlag(flag, value);
@ -85,61 +82,62 @@ function setOnSystemFlag(flag) { setSystemFlag(flag, true); }
function setOffSystemFlag(flag) { setSystemFlag(flag, false); } function setOffSystemFlag(flag) { setSystemFlag(flag, false); }
``` ```
A callable may have any number of parameters. Each of the callable's parameters is dynamically typed.
Each parameter is dynamically typed. A builtin may have a variadic signature by specifying the ellipsis identifier `...` as the final parameter:
A builtin may have a variadic signature by specifying an ellipsis keyword `...` as the final parameter (variadic functions are **not** supported):
```javascript ```
builtin print(...); // variadic builtin builtin print(...); // variadic builtin
print("Hello, ", "world!"); // this is legal print("Hello, ", "world!"); // this is legal
print("I have ", 3, " arguments."); // so is this print("I have ", 3, " arguments."); // so is this
``` ```
> **Note:** Variadic functions are _not_ supported.
A callable's return value is also dynamic. 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. 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 appearReadyGo(); // calls the function 'appearReadyGo' with no arguments
insertTimer(1, 0); // calls the function 'insertTimer' with two arguments, '1' and '0' 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 ### Modifiers
A declared symbol may be assigned compile-time modifiers. A declared symbol may be assigned compile-time modifiers.
The modifiers follow their respective keywords in their declaration/definition: The modifiers follow their respective keywords in their declaration/definition:
```javascript ```
var foo; // global symbol (can be resolved from other scripts) var foo; // global script symbol (can be resolved from other scripts)
var local bar; // global symbol (can be resolved only from the current script) var local bar; // local script symbol (can be resolved only from the current script)
function local const getBaz() { function local const getBaz() {
return 132; 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| |Modifier|Description|
|--------|-----------| |--------|-----------|
|`local`|Resolves only within the current script file. Applies to only script-scope symbols.| |`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: The following matrix details which symbol types support which modifiers:
|type|`local`|`const`| |type|`local`|`const`|
|----|:-----:|:-----:| |----|:-----:|:-----:|
|variable|✓| | |variable|✓|✓|
|constant|✓| |
|function|✓|✓| |function|✓|✓|
|builtin| |✓| |builtin| |✓|
@ -165,34 +163,61 @@ The following table describes the operators supported by SunScript, as well as t
### Flow Control ### 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) { var coinNum = getSystemFlag(SYSF_GOLDCOINNUM);
if (time < 30) { if (coinNum >= needCoinNum) {
startMiss(); setSystemFlag(SYSF_GOLDCOINNUM, coinNum - needCoinNum);
exit; startEventSE(1);
} talkAndClose(0xD0019);
yield;
setNextStage(20, 0);
} }
var i = 0; else {
while (i < 100) { talkAndClose(0xD001A);
checkTime(i);
if (stop) {
break;
}
} }
``` ```
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 #### 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. 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: `break` and `continue` statements may be passed the name of the loop which they affect:
```javascript ```
outer_loop: outer_loop:
for (var a; a < 4; ++a) { for (var a = 0; a < 4; ++a) {
for (var b; b < 4; ++b) { for (var b = 0; b < 4; ++b) {
if (b == 2) break outer_loop; 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. Doing this requires the use of the `import` statement.
Simply pass the name of the SunScript file to import: Simply pass the name of the SunScript file to import:
```javascript ```
import "ssc/common.sun";
import "constants.sun"; import "constants.sun";
import "C:/math.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. 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. 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. - 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.

View file

@ -14,7 +14,11 @@ namespace arookas {
: base(location) { } : base(location) { }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
compiler.Context.DeclareBuiltin(this); 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
}
} }
} }
@ -33,7 +37,8 @@ namespace arookas {
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
// this defines the function in the context // this defines the function in the context
// it doesn't compile the definition body // it doesn't compile the definition body
compiler.Context.DefineFunction(this); var symbol = compiler.Context.DefineFunction(this);
symbol.Modifiers = Modifiers;
} }
} }

View file

@ -1,11 +1,11 @@
namespace arookas { namespace arookas {
class sunConstKeyword : sunNode { class sunConstModifier : sunNode {
public sunConstKeyword(sunSourceLocation location) public sunConstModifier(sunSourceLocation location)
: base(location) { } : base(location) { }
} }
class sunLocalKeyword : sunNode { class sunLocalModifier : sunNode {
public sunLocalKeyword(sunSourceLocation location) public sunLocalModifier(sunSourceLocation location)
: base(location) { } : base(location) { }
} }
} }

View file

@ -32,7 +32,11 @@
: base(location) { } : base(location) { }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
compiler.Context.DeclareVariable(this); var symbol = compiler.Context.DeclareVariable(this);
symbol.Modifiers = Modifiers;
if ((Modifiers & sunSymbolModifiers.Constant) != 0) {
throw new sunInvalidModifierException(this[0]);
}
} }
} }
@ -49,8 +53,24 @@
: base(location) { } : base(location) { }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
var symbol = compiler.Context.DeclareVariable(this); // create the right type of symbol based on the const modifier
Operator.Compile(compiler, symbol, Expression); 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);
}
} }
} }
@ -70,27 +90,4 @@
Operator.Compile(compiler, symbol, Expression); 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);
}
}
} }

View file

@ -131,7 +131,7 @@ namespace arookas {
#endif #endif
void CompileRelocations() { void CompileRelocations() {
foreach (var symbol in mContext.SymbolTable) { foreach (var symbol in mContext.SymbolTable) {
symbol.CloseRelocations(this); symbol.CloseRelocations();
} }
} }
void CompileData() { void CompileData() {

View file

@ -111,7 +111,7 @@ namespace arookas {
} }
return symbol; return symbol;
} }
public sunConstantSymbol DeclareConstant(sunConstantDefinition node) { public sunConstantSymbol DeclareConstant(sunVariableDefinition node) {
return DeclareConstant(node.Name, node.Expression, node.Modifiers); return DeclareConstant(node.Name, node.Expression, node.Modifiers);
} }
sunConstantSymbol DeclareConstant(sunIdentifier node, sunExpression expression, sunSymbolModifiers modifiers) { sunConstantSymbol DeclareConstant(sunIdentifier node, sunExpression expression, sunSymbolModifiers modifiers) {

View file

@ -251,4 +251,12 @@ namespace arookas {
public sunContinueException(sunContinue node) public sunContinueException(sunContinue node)
: base(node) { } : base(node) { }
} }
class sunInvalidModifierException : sunNodeException<sunNode> {
public override string Message {
get { return "Unsupported modifier in modifier list."; }
}
public sunInvalidModifierException(sunNode node)
: base(node) { }
}
} }

View file

@ -190,12 +190,6 @@ namespace arookas {
case __sunConstants.VARIABLE_AUGMENT: return new sunNode(location); 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 // flow control
switch (id) { switch (id) {
case __sunConstants.IF_STATEMENT: return new sunIf(location); case __sunConstants.IF_STATEMENT: return new sunIf(location);
@ -211,17 +205,10 @@ namespace arookas {
case __sunConstants.CONTINUE_STATEMENT: return new sunContinue(location); case __sunConstants.CONTINUE_STATEMENT: return new sunContinue(location);
} }
// keywords // modifiers
if (id == __sunConstants.CONST) { switch (id) {
switch (parent) { case __sunConstants.LOCAL: return new sunLocalModifier(location);
case __sunConstants.FUNCTION_MODIFIERS: case __sunConstants.CONST: return new sunConstModifier(location);
case __sunConstants.BUILTIN_MODIFIERS: {
return new sunConstKeyword(location);
}
}
}
if (id == __sunConstants.LOCAL) {
return new sunLocalKeyword(location);
} }
// emergency fallback // emergency fallback

View file

@ -53,7 +53,7 @@ namespace arookas {
mStack.Add(new sunScope(type)); mStack.Add(new sunScope(type));
} }
#endif #endif
public void Pop(sunCompiler compiler) { public void Pop() {
if (Count > 1) { if (Count > 1) {
#if SSC_SCOPES #if SSC_SCOPES
if (Top.Type == sunScopeType.Script) { if (Top.Type == sunScopeType.Script) {
@ -62,7 +62,7 @@ namespace arookas {
#else #else
// close relocations while we still have references to the symbols // close relocations while we still have references to the symbols
foreach (var variable in Top) { foreach (var variable in Top) {
variable.CloseRelocations(compiler); variable.CloseRelocations();
} }
#endif #endif
mStack.RemoveAt(Count - 1); mStack.RemoveAt(Count - 1);

View file

@ -124,7 +124,6 @@ statement =
statement_block; statement_block;
compound_statement = compound_statement_item {COMMA compound_statement_item}; compound_statement = compound_statement_item {COMMA compound_statement_item};
compound_statement_item = compound_statement_item =
const_definition |
variable_definition | variable_definition |
variable_declaration | variable_declaration |
variable_assignment | variable_assignment |
@ -170,15 +169,11 @@ term =
unary_operator_list = unary_operator+; unary_operator_list = unary_operator+;
// constants
const_definition = const_modifiers IDENTIFIER ASSIGN expression;
const_modifiers = CONST [LOCAL];
// variables // variables
variable_reference = IDENTIFIER; // used in expressions variable_reference = IDENTIFIER; // used in expressions
variable_declaration = variable_modifiers IDENTIFIER; variable_declaration = variable_modifiers IDENTIFIER;
variable_definition = variable_modifiers IDENTIFIER ASSIGN expression; variable_definition = variable_modifiers IDENTIFIER ASSIGN expression;
variable_modifiers = VAR [LOCAL]; variable_modifiers = VAR [LOCAL] [CONST];
variable_assignment = IDENTIFIER assignment_operator expression; variable_assignment = IDENTIFIER assignment_operator expression;
variable_augment = postfix_augment | prefix_augment; variable_augment = postfix_augment | prefix_augment;

View file

@ -90,12 +90,10 @@ namespace arookas {
} }
mRelocations.Add(relocation); mRelocations.Add(relocation);
} }
public void CloseRelocations(sunCompiler compiler) { public void CloseRelocations() {
compiler.Binary.Keep();
foreach (var relocation in mRelocations) { foreach (var relocation in mRelocations) {
relocation.Relocate(); relocation.Relocate();
} }
compiler.Binary.Back();
} }
public static sunSymbolModifiers GetModifiers(sunNode modifierlist) { public static sunSymbolModifiers GetModifiers(sunNode modifierlist) {
@ -103,10 +101,10 @@ namespace arookas {
return sunSymbolModifiers.None; return sunSymbolModifiers.None;
} }
var modifiers = sunSymbolModifiers.None; var modifiers = sunSymbolModifiers.None;
if (modifierlist.Any(i => i is sunConstKeyword)) { if (modifierlist.Any(i => i is sunConstModifier)) {
modifiers |= sunSymbolModifiers.Constant; modifiers |= sunSymbolModifiers.Constant;
} }
if (modifierlist.Any(i => i is sunLocalKeyword)) { if (modifierlist.Any(i => i is sunLocalModifier)) {
modifiers |= sunSymbolModifiers.Local; modifiers |= sunSymbolModifiers.Local;
} }
return modifiers; return modifiers;
@ -202,7 +200,7 @@ namespace arookas {
} }
mBody.Compile(compiler); mBody.Compile(compiler);
compiler.Binary.WriteRET0(); compiler.Binary.WriteRET0();
compiler.Context.Scopes.Pop(compiler); compiler.Context.Scopes.Pop();
++mCompiles; ++mCompiles;
} }
public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) { public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) {
@ -289,8 +287,6 @@ namespace arookas {
get { return (uint)Index; } get { return (uint)Index; }
} }
public sunVariableSymbol(string name)
: this(name, 0, 0) { }
public sunVariableSymbol(string name, int display, int index) public sunVariableSymbol(string name, int display, int index)
: base(name) { : base(name) {
mDisplay = display; mDisplay = display;
@ -349,7 +345,7 @@ namespace arookas {
[Flags] [Flags]
enum sunSymbolModifiers { enum sunSymbolModifiers {
None = 0, None = 0,
Constant = 1 << 0, Local = 1 << 0,
Local = 1 << 1, Constant = 1 << 1,
} }
} }

View file

@ -10,9 +10,9 @@ builtin const int(x);
builtin const float(x); builtin const float(x);
builtin const typeof(x); builtin const typeof(x);
const TYPE_INT = 0; var const TYPE_INT = 0;
const TYPE_FLOAT = 1; var const TYPE_FLOAT = 1;
const TYPE_STRING = 2; var const TYPE_STRING = 2;
// debug // debug
builtin dump(); builtin dump();

View file

@ -15,49 +15,49 @@ builtin startMontemanBGM();
builtin startMontemanFanfare(); builtin startMontemanFanfare();
// [arookas] these are from mSound.asn // [arookas] these are from mSound.asn
const MSD_BGM_DOLPIC = 0x80010001; var const MSD_BGM_DOLPIC = 0x80010001;
const MSD_BGM_BIANCO = 0x80010002; var const MSD_BGM_BIANCO = 0x80010002;
const MSD_BGM_MAMMA = 0x80010003; var const MSD_BGM_MAMMA = 0x80010003;
const MSD_BGM_PINNAPACO_SEA = 0x80010004; var const MSD_BGM_PINNAPACO_SEA = 0x80010004;
const MSD_BGM_PINNAPACO = 0x80010005; var const MSD_BGM_PINNAPACO = 0x80010005;
const MSD_BGM_MARE_SEA = 0x80010006; var const MSD_BGM_MARE_SEA = 0x80010006;
const MSD_BGM_MONTEVILLAGE = 0x80010007; var const MSD_BGM_MONTEVILLAGE = 0x80010007;
const MSD_BGM_SHILENA = 0x80010008; var const MSD_BGM_SHILENA = 0x80010008;
const MSD_BGM_RICCO = 0x80010009; var const MSD_BGM_RICCO = 0x80010009;
const MSD_BGM_GET_SHINE = 0x8001000A; var const MSD_BGM_GET_SHINE = 0x8001000A;
const MSD_BGM_CHUBOSS = 0x8001000B; var const MSD_BGM_CHUBOSS = 0x8001000B;
const MSD_BGM_MISS = 0x8001000C; var const MSD_BGM_MISS = 0x8001000C;
const MSD_BGM_BOSS = 0x8001000D; var const MSD_BGM_BOSS = 0x8001000D;
const MSD_BGM_MAP_SELECT = 0x8001000E; var const MSD_BGM_MAP_SELECT = 0x8001000E;
const MSD_BGM_BOSSPAKU_DEMO = 0x8001000F; var const MSD_BGM_BOSSPAKU_DEMO = 0x8001000F;
const MSD_BGM_MAIN_TITLE = 0x80010010; var const MSD_BGM_MAIN_TITLE = 0x80010010;
const MSD_BGM_CHUBOSS2 = 0x80010011; var const MSD_BGM_CHUBOSS2 = 0x80010011;
const MSD_BGM_EXTRA = 0x80010012; var const MSD_BGM_EXTRA = 0x80010012;
const MSD_BGM_DELFINO = 0x80010013; var const MSD_BGM_DELFINO = 0x80010013;
const MSD_BGM_MAREVILLAGE = 0x80010014; var const MSD_BGM_MAREVILLAGE = 0x80010014;
const MSD_BGM_CORONA = 0x80010015; var const MSD_BGM_CORONA = 0x80010015;
const MSD_BGM_KAGEMARIO = 0x80010016; var const MSD_BGM_KAGEMARIO = 0x80010016;
const MSD_BGM_CAMERA = 0x80010017; var const MSD_BGM_CAMERA = 0x80010017;
const MSD_BGM_MONTE_ONSEN = 0x80010018; var const MSD_BGM_MONTE_ONSEN = 0x80010018;
const MSD_BGM_MECHAKUPPA = 0x80010019; var const MSD_BGM_MECHAKUPPA = 0x80010019;
const MSD_BGM_AIRPORT = 0x8001001A; var const MSD_BGM_AIRPORT = 0x8001001A;
const MSD_BGM_UNDERGROUND = 0x8001001B; var const MSD_BGM_UNDERGROUND = 0x8001001B;
const MSD_BGM_TITLEBACK = 0x8001001C; var const MSD_BGM_TITLEBACK = 0x8001001C;
const MSD_BGM_MONTE_NIGHT = 0x8001001D; var const MSD_BGM_MONTE_NIGHT = 0x8001001D;
const MSD_BGM_CASINO = 0x8001001E; var const MSD_BGM_CASINO = 0x8001001E;
const MSD_BGM_EVENT = 0x8001001F; var const MSD_BGM_EVENT = 0x8001001F;
const MSD_BGM_TIME_IVENT = 0x80010020; var const MSD_BGM_TIME_IVENT = 0x80010020;
const MSD_BGM_SKY_AND_SEA = 0x80010021; var const MSD_BGM_SKY_AND_SEA = 0x80010021;
const MSD_BGM_MONTE_RESCUE = 0x80010022; var const MSD_BGM_MONTE_RESCUE = 0x80010022;
const MSD_BGM_MERRY_GO_ROUND = 0x80010023; var const MSD_BGM_MERRY_GO_ROUND = 0x80010023;
const MSD_BGM_SCENARIO_SELECT = 0x80010024; var const MSD_BGM_SCENARIO_SELECT = 0x80010024;
const MSD_BGM_FANFARE_CASINO = 0x80010025; var const MSD_BGM_FANFARE_CASINO = 0x80010025;
const MSD_BGM_FANFARE_RACE = 0x80010026; var const MSD_BGM_FANFARE_RACE = 0x80010026;
const MSD_BGM_CAMERA_KAGE = 0x80010027; var const MSD_BGM_CAMERA_KAGE = 0x80010027;
const MSD_BGM_GAMEOVER = 0x80010028; var const MSD_BGM_GAMEOVER = 0x80010028;
const MSD_BGM_BOSSHANA_2ND3RD = 0x80010029; var const MSD_BGM_BOSSHANA_2ND3RD = 0x80010029;
const MSD_BGM_BOSSGESO_2DN3RD = 0x8001002A; var const MSD_BGM_BOSSGESO_2DN3RD = 0x8001002A;
const MSD_BGM_CHUBOSS_MANTA = 0x8001002B; var const MSD_BGM_CHUBOSS_MANTA = 0x8001002B;
const MSD_BGM_MONTE_LAST = 0x8001002C; var const MSD_BGM_MONTE_LAST = 0x8001002C;
const MSD_BGM_SHINE_APPEAR = 0x8001002D; var const MSD_BGM_SHINE_APPEAR = 0x8001002D;
const MSD_BGM_KUPPA = 0x8001002E; var const MSD_BGM_KUPPA = 0x8001002E;

View file

@ -10,19 +10,19 @@
// ================================================= \\ // ================================================= \\
// known flags here // known flags here
const SYS_SHINEGET = 0x10000; // add shine num to this var const SYSF_SHINEGET = 0x10000; // add shine num to this
const SYS_MARIOLIVES = 0x20001; var const SYSF_MARIOLIVES = 0x20001;
const SYS_SHINENUM = 0x40000; var const SYSF_SHINENUM = 0x40000;
const SYS_BLUECOINNUM = 0x40001; var const SYSF_BLUECOINNUM = 0x40001;
const SYS_GOLDCOINNUM = 0x40002; var const SYSF_GOLDCOINNUM = 0x40002;
builtin getSystemFlag(flag); builtin getSystemFlag(flag);
builtin setSystemFlag(flag, value); builtin setSystemFlag(flag, value);
function setOnSystemFlag(flag) { setSystemFlag(flag, true); } function setOnSystemFlag(flag) { setSystemFlag(flag, true); }
function setOffSystemFlag(flag) { setSystemFlag(flag, false); } function setOffSystemFlag(flag) { setSystemFlag(flag, false); }
// [arookas] custom utility // [arookas] custom utility
function incSystemFlag(flag) { function incSystemFlag(flag) {
@ -62,16 +62,10 @@ builtin startMareBottleDemo();
builtin isFinishMareBottleDemo(); builtin isFinishMareBottleDemo();
function waitForFinishDemo() { function waitForFinishDemo() {
while (true) { while (!isDemoMode()) {
if (isDemoMode()) {
break;
}
yield; yield;
} }
while (true) { while (isDemoMode()) {
if (isDemoMode() == false) {
break;
}
yield; yield;
} }
} }

View file

@ -10,8 +10,8 @@
// ================================================= \\ // ================================================= \\
// flags // flags
const TALKF_WAIT = 0; var const TALKF_WAIT = 0;
const TALKF_CLOSE = (1 << 0); var const TALKF_CLOSE = (1 << 0);
// builtins // builtins
builtin getTalkMode(); builtin getTalkMode();
@ -56,14 +56,14 @@ function talk(msgID, flags) {
} }
else { else {
yield; yield;
while (getTalkMode() != true) { while (!getTalkMode()) {
yield; yield;
} }
} }
} }
function talkAndWait(msgID) { talk(msgID, TALKF_WAIT); } function talkAndWait(msgID) { talk(msgID, TALKF_WAIT); }
function talkAndClose(msgID) { talk(msgID, TALKF_CLOSE); } function talkAndClose(msgID) { talk(msgID, TALKF_CLOSE); }
// ================================================= \\ // ================================================= \\
// SELECT // SELECT
@ -81,16 +81,15 @@ function select(msgID, flags) {
} }
} }
else { else {
yield; do {
while (getTalkMode() != true) {
yield; yield;
} } while (!getTalkMode());
} }
return getTalkSelectedValue(); return getTalkSelectedValue();
} }
function talkAndSelect(msgID) { return select(msgID, TALKF_WAIT); } function talkAndSelect(msgID) { return select(msgID, TALKF_WAIT); }
function talkAndSelectClose(msgID) { return select(msgID, TALKF_CLOSE); } function talkAndSelectClose(msgID) { return select(msgID, TALKF_CLOSE); }
// ================================================= \\ // ================================================= \\
// FORCE // FORCE
@ -103,20 +102,20 @@ builtin forceCloseTalk();
// functions // functions
function forceTalk(handle) { function forceTalk(handle) {
var res = __forceStartTalk(handle); var result = __forceStartTalk(handle);
if (res == true) { if (result) {
while (!isTalkModeNow()) { while (!isTalkModeNow()) {
yield; yield;
} }
} }
return res; return result;
} }
function forceTalkExceptNpc(handle) { function forceTalkExceptNpc(handle) {
var res = __forceStartTalkExceptNpc(handle); var result = __forceStartTalkExceptNpc(handle);
if (res == true) { if (result) {
while (!isTalkModeNow()) { while (!isTalkModeNow()) {
yield; yield;
} }
} }
return res; return result;
} }