mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-25 20:49:57 +03:00
More small stuff before I work no spatial stuff.
This commit is contained in:
parent
eb98e15f49
commit
62a6d18673
4 changed files with 79 additions and 66 deletions
6
rin/examples/error.rin
Executable file
6
rin/examples/error.rin
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/env rin
|
||||
|
||||
## A script that exists to show how errors look.
|
||||
|
||||
$ 1 2 + +
|
||||
$ bababababababbabababab bababababababababba CAT
|
|
@ -6,10 +6,10 @@ import parin.story;
|
|||
RinState rinState;
|
||||
|
||||
enum helpMsg = `
|
||||
Usage:
|
||||
Usage
|
||||
rin [options] script
|
||||
rin [options] -e expression
|
||||
Options:
|
||||
Options
|
||||
-d Executes in debug mode.
|
||||
-l Executes in linear mode.
|
||||
-e Executes a single expression.
|
||||
|
@ -32,15 +32,15 @@ IStr prepareErrorMsg(Fault fault) {
|
|||
IStr updateErrorMsg(Fault fault) {
|
||||
switch (fault) with (Fault) {
|
||||
case assertion: return "Assertion failed.";
|
||||
case invalid: return "Invalid arguments passed to the `{}` operator.".format(rinState.story.faultOp);
|
||||
case overflow: return "A word or number is too long.";
|
||||
case cantParse: return "A word, number, or operator contains invalid characters.";
|
||||
case invalid: return "Invalid values passed to `{}` at token position `{}`.".format(rinState.story.faultOp, rinState.story.faultTokenPosition);
|
||||
case overflow: return "A value is too long at token position `{}`.".format(rinState.story.faultTokenPosition);
|
||||
case cantParse: return "A value or operator contains invalid characters at token position `{}`.".format(rinState.story.faultTokenPosition);
|
||||
default: return "WTF!";
|
||||
}
|
||||
}
|
||||
|
||||
void printScriptError(Sz index, IStr text) {
|
||||
printfln("\n{}({}): {}", rinState.scriptPath, index, text);
|
||||
printfln("{}:{}\n {}", rinState.scriptPath, index, text);
|
||||
}
|
||||
|
||||
Fault prepareStory() {
|
||||
|
|
|
@ -881,7 +881,6 @@ struct EngineViewport {
|
|||
|
||||
/// The engine state.
|
||||
struct EngineState {
|
||||
// LABEL
|
||||
EngineFlags flags;
|
||||
EngineFullscreenState fullscreenState;
|
||||
Sz tickCount;
|
||||
|
@ -2429,15 +2428,9 @@ void drawDebugText(IStr text, Vec2 position, DrawOptions options = DrawOptions()
|
|||
/// Mixes in a game loop template with specified functions for initialization, update, and cleanup, and sets window size and title.
|
||||
mixin template runGame(alias readyFunc, alias updateFunc, alias finishFunc, int width = 960, int height = 540, IStr title = "Parin") {
|
||||
version (D_BetterC) {
|
||||
// NOTE: This is unsafe, so avoid reserving memory for envArgsBuffer.
|
||||
@trusted @nogc nothrow
|
||||
void __mainArgcArgvThing(int argc, immutable(char)** argv) {
|
||||
foreach (i; 0 .. argc) engineState.envArgsBuffer.append(argv[i].toStr());
|
||||
}
|
||||
|
||||
extern(C)
|
||||
void main(int argc, immutable(char)** argv) {
|
||||
__mainArgcArgvThing(argc, argv);
|
||||
foreach (i; 0 .. argc) engineState.envArgsBuffer.append(argv[i].toStr());
|
||||
openWindow(width, height, engineState.envArgsBuffer[], title);
|
||||
readyFunc();
|
||||
updateWindow(&updateFunc);
|
||||
|
@ -2445,7 +2438,7 @@ mixin template runGame(alias readyFunc, alias updateFunc, alias finishFunc, int
|
|||
closeWindow();
|
||||
}
|
||||
} else {
|
||||
void main(string[] args) {
|
||||
void main(immutable(char)[][] args) {
|
||||
openWindow(width, height, args, title);
|
||||
readyFunc();
|
||||
updateWindow(&updateFunc);
|
||||
|
|
|
@ -131,6 +131,7 @@ struct Story {
|
|||
StoryNumber previousMenuResult;
|
||||
StoryNumber faultPrepareIndex;
|
||||
StoryOp faultOp;
|
||||
Sz faultTokenPosition;
|
||||
bool debugMode;
|
||||
bool linearMode;
|
||||
|
||||
|
@ -203,8 +204,9 @@ struct Story {
|
|||
return opIndex(lineIndex)[1 .. $].trimStart();
|
||||
}
|
||||
|
||||
Fault throwOpFault(StoryOp op) {
|
||||
Fault throwOpFault(StoryOp op, Sz position) {
|
||||
faultOp = op;
|
||||
faultTokenPosition = position;
|
||||
return Fault.invalid;
|
||||
}
|
||||
|
||||
|
@ -301,9 +303,11 @@ struct Story {
|
|||
|
||||
stack.clear();
|
||||
auto ifCounter = 0;
|
||||
auto tokenCount = 0;
|
||||
while (true) with (StoryOp) {
|
||||
if (expression.length == 0) break;
|
||||
auto token = expression.skipValue(' ');
|
||||
tokenCount += 1;
|
||||
expression = expression.trimStart();
|
||||
if (token.length == 0) continue;
|
||||
if (ifCounter > 0) {
|
||||
|
@ -326,10 +330,10 @@ struct Story {
|
|||
case LESS:
|
||||
case GREATER:
|
||||
case EQUAL:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryNumber || !db.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryNumber || !db.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryNumber;
|
||||
auto b = db.get!StoryNumber;
|
||||
auto c = StoryNumber.init;
|
||||
|
@ -349,9 +353,9 @@ struct Story {
|
|||
stack.append(StoryValue(c));
|
||||
break;
|
||||
case NOT:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
stack.append(StoryValue(!da.get!StoryNumber));
|
||||
break;
|
||||
case POP:
|
||||
|
@ -361,36 +365,36 @@ struct Story {
|
|||
stack.clear();
|
||||
break;
|
||||
case SWAP:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
stack.append(db);
|
||||
stack.append(da);
|
||||
break;
|
||||
case COPY:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
stack.append(stack[$ - 1]);
|
||||
break;
|
||||
case COPYN:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
stack.append(stack[$ - 2]);
|
||||
stack.append(stack[$ - 2]);
|
||||
break;
|
||||
case RANGE:
|
||||
if (stack.length < 3) return throwOpFault(op);
|
||||
if (stack.length < 3) return throwOpFault(op, tokenCount);
|
||||
auto dc = stack.pop();
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryNumber || !db.isType!StoryNumber || !dc.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryNumber || !db.isType!StoryNumber || !dc.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryNumber();
|
||||
auto b = db.get!StoryNumber();
|
||||
auto c = dc.get!StoryNumber();
|
||||
stack.append(StoryValue(a >= b && a <= c));
|
||||
break;
|
||||
case IF:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
if (!da.get!StoryNumber) ifCounter += 1;
|
||||
break;
|
||||
case ELSE:
|
||||
|
@ -399,18 +403,21 @@ struct Story {
|
|||
case THEN:
|
||||
break;
|
||||
case CAT:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
StoryWord word;
|
||||
auto data = concat(da.toStr(), db.toStr());
|
||||
auto tempWordRef = word[];
|
||||
if (auto fault = tempWordRef.copyChars(data)) return fault;
|
||||
if (auto fault = tempWordRef.copyChars(data)) {
|
||||
faultTokenPosition = tokenCount;
|
||||
return fault;
|
||||
}
|
||||
stack.append(StoryValue(word));
|
||||
break;
|
||||
case SAME:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
auto a = da.get!StoryWord;
|
||||
|
@ -418,12 +425,12 @@ struct Story {
|
|||
stack.append(StoryValue(a == b));
|
||||
break;
|
||||
case WORD:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
stack.append(StoryValue(da.isType!StoryWord));
|
||||
break;
|
||||
case NUMBER:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
stack.append(StoryValue(da.isType!StoryNumber));
|
||||
break;
|
||||
|
@ -481,29 +488,29 @@ struct Story {
|
|||
}
|
||||
break;
|
||||
case HERE:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
stack.append(StoryValue(findVariable(a) != -1));
|
||||
break;
|
||||
case GET:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
stack.append(variables[aIndex].value);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
case GETN:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord || !db.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord || !db.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto b = db.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
|
@ -512,14 +519,14 @@ struct Story {
|
|||
stack.append(variables[aIndex].value);
|
||||
stack.append(variables[bIndex].value);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
case SET:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
|
@ -529,9 +536,9 @@ struct Story {
|
|||
}
|
||||
break;
|
||||
case INIT:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
|
@ -541,9 +548,9 @@ struct Story {
|
|||
}
|
||||
break;
|
||||
case DROP:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
|
@ -555,9 +562,9 @@ struct Story {
|
|||
break;
|
||||
case INC:
|
||||
case DEC:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
|
@ -565,18 +572,18 @@ struct Story {
|
|||
variables[aIndex].value.get!StoryNumber() += (op == INC ? 1 : -1);
|
||||
stack.append(variables[aIndex].value);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
case INCN:
|
||||
case DECN:
|
||||
if (stack.length < 2) return throwOpFault(op);
|
||||
if (stack.length < 2) return throwOpFault(op, tokenCount);
|
||||
auto db = stack.pop();
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord || !db.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord || !db.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto b = db.get!StoryNumber();
|
||||
auto aIndex = findVariable(a);
|
||||
|
@ -585,16 +592,16 @@ struct Story {
|
|||
variables[aIndex].value.get!StoryNumber() += b * (op == INCN ? 1 : -1);
|
||||
stack.append(variables[aIndex].value);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
case TOG:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findVariable(a);
|
||||
if (aIndex != -1) {
|
||||
|
@ -602,10 +609,10 @@ struct Story {
|
|||
variables[aIndex].value.get!StoryNumber() = !variables[aIndex].value.get!StoryNumber();
|
||||
stack.append(variables[aIndex].value);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
case MENU:
|
||||
|
@ -621,9 +628,9 @@ struct Story {
|
|||
}
|
||||
break;
|
||||
case SKIP:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op);
|
||||
if (!da.isType!StoryNumber) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryNumber();
|
||||
if (a == 0) break;
|
||||
if (linearMode) break;
|
||||
|
@ -635,29 +642,36 @@ struct Story {
|
|||
}
|
||||
break;
|
||||
case JUMP:
|
||||
if (stack.length < 1) return throwOpFault(op);
|
||||
if (stack.length < 1) return throwOpFault(op, tokenCount);
|
||||
auto da = stack.pop();
|
||||
if (!da.isType!StoryWord) return throwOpFault(op);
|
||||
if (!da.isType!StoryWord) return throwOpFault(op, tokenCount);
|
||||
auto a = da.get!StoryWord();
|
||||
auto aIndex = findLabel(a);
|
||||
if (aIndex != -1) {
|
||||
if (linearMode) break;
|
||||
jumpLineIndex(aIndex);
|
||||
} else {
|
||||
return throwOpFault(op);
|
||||
return throwOpFault(op, tokenCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (token.isMaybeStoryNumber) {
|
||||
auto number = token.toSigned();
|
||||
if (number.isNone) return number.fault;
|
||||
if (number.isNone) {
|
||||
faultTokenPosition = tokenCount;
|
||||
return number.fault;
|
||||
}
|
||||
stack.append(StoryValue(cast(StoryNumber) number.value));
|
||||
} else if (token.isMaybeStoryWord) {
|
||||
auto word = StoryWord.init;
|
||||
auto wordRef = word[];
|
||||
if (auto fault = wordRef.copyChars(token)) return fault;
|
||||
if (auto fault = wordRef.copyChars(token)) {
|
||||
faultTokenPosition = tokenCount;
|
||||
return fault;
|
||||
}
|
||||
stack.append(StoryValue(word));
|
||||
} else {
|
||||
faultTokenPosition = tokenCount;
|
||||
return Fault.cantParse;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue