1
0

Implement LINPUT

This commit is contained in:
otya128
2016-12-29 17:59:47 +09:00
parent c0f1e4e9e5
commit 20889c28e1
5 changed files with 80 additions and 0 deletions

View File

@@ -2551,3 +2551,13 @@ class GosubUndefinedLabel : Code
throw new UndefinedLabel(label); throw new UndefinedLabel(label);
} }
} }
class Linput : Code
{
override void execute(VM vm)
{
Value guide;
vm.pop(guide);
vm.push(Value(vm.petitcomputer.input(guide.castDString, false)));
}
}

View File

@@ -941,6 +941,15 @@ class Compiler
compileExpression(use.expression, sc); compileExpression(use.expression, sc);
genCode(new otya.smilebasic.vm.Use); genCode(new otya.smilebasic.vm.Use);
} }
void compileLinput(otya.smilebasic.node.Linput linput, Scope sc)
{
if (linput.hasGuide)
compileExpression(linput.guide, sc);
else
genCodeImm(Value(""));
genCode(new otya.smilebasic.vm.Linput);
compilePopVar(linput.expression, sc);
}
void compileStatement(Statement i, Scope s) void compileStatement(Statement i, Scope s)
{ {
switch(i.type) switch(i.type)
@@ -1215,6 +1224,9 @@ class Compiler
case NodeType.Use: case NodeType.Use:
compileUse(cast(otya.smilebasic.node.Use)i, s); compileUse(cast(otya.smilebasic.node.Use)i, s);
break; break;
case NodeType.Linput:
compileLinput(cast(otya.smilebasic.node.Linput)i, s);
break;
default: default:
stderr.writeln("Compile:NotImpl ", i.type); stderr.writeln("Compile:NotImpl ", i.type);
} }

View File

@@ -50,6 +50,7 @@ enum NodeType
XOff, XOff,
Exec, Exec,
Use, Use,
Linput,
} }
abstract class Node abstract class Node
{ {
@@ -675,3 +676,24 @@ class Use : Statement
this.type = NodeType.Use; this.type = NodeType.Use;
} }
} }
class Linput : Statement
{
bool hasGuide;
Expression guide;
Expression expression;
this(Expression guide, Expression expr, SourceLocation loc)
{
super.location = loc;
this.type = NodeType.Linput;
this.hasGuide = true;
this.guide = guide;
this.expression = expr;
}
this(Expression expr, SourceLocation loc)
{
super.location = loc;
this.type = NodeType.Linput;
this.hasGuide = false;
this.expression = expr;
}
}

View File

@@ -82,6 +82,7 @@ class Lexical
reserved["REPEAT"] = TokenType.Repeat; reserved["REPEAT"] = TokenType.Repeat;
reserved["UNTIL"] = TokenType.Until; reserved["UNTIL"] = TokenType.Until;
reserved["SWAP"] = TokenType.Swap; reserved["SWAP"] = TokenType.Swap;
reserved["LINPUT"] = TokenType.Linput;
reserved.rehash(); reserved.rehash();
} }
this(wstring input) this(wstring input)
@@ -1124,6 +1125,8 @@ class Parser
break; break;
case TokenType.Swap: case TokenType.Swap:
return swapStatement(); return swapStatement();
case TokenType.Linput:
return linputStatement();
default: default:
syntaxError(); syntaxError();
break; break;
@@ -1131,6 +1134,38 @@ class Parser
lex.popFront(); lex.popFront();
return node; return node;
} }
Linput linputStatement()
{
auto location = lex.location;
lex.popFront();
Expression message = expression();
if(!message)
{
syntaxError();
return null;
}
auto token = lex.front();
if (token.type == TokenType.Semicolon)
{
lex.popFront();
Expression var = expression();
if (!isLValue(var))
{
syntaxError();
return null;
}
return new Linput(message, var, location);
}
else
{
if (!isLValue(message))
{
syntaxError();
return null;
}
return new Linput(message, location);
}
}
Swap swapStatement() Swap swapStatement()
{ {
lex.popFront(); lex.popFront();

View File

@@ -76,6 +76,7 @@ enum TokenType
Swap, Swap,
Dim, Dim,
Constant, Constant,
Linput,
} }
enum TokenValueType enum TokenValueType