2015-06-03 19:51:42 +09:00
|
|
|
module otya.smilebasic.token;
|
|
|
|
|
import otya.smilebasic.type;
|
2016-12-17 11:55:07 +09:00
|
|
|
import std.exception;
|
2015-06-03 19:51:42 +09:00
|
|
|
enum TokenType
|
|
|
|
|
{
|
|
|
|
|
Unknown,
|
|
|
|
|
Integer,
|
|
|
|
|
Double,
|
|
|
|
|
String,
|
|
|
|
|
Plus,
|
|
|
|
|
Minus,
|
|
|
|
|
Mul,
|
|
|
|
|
Div,
|
|
|
|
|
Mod,
|
|
|
|
|
Or,
|
|
|
|
|
And,
|
|
|
|
|
Xor,
|
2015-06-04 19:31:47 +09:00
|
|
|
Not,
|
2015-06-03 19:51:42 +09:00
|
|
|
Print,
|
|
|
|
|
If,
|
2015-06-03 21:18:55 +09:00
|
|
|
LParen,
|
|
|
|
|
RParen,
|
2015-06-03 21:52:09 +09:00
|
|
|
Iden,
|
|
|
|
|
Comma,
|
2015-06-04 19:31:47 +09:00
|
|
|
Colon,
|
|
|
|
|
Semicolon,
|
2015-06-04 19:57:40 +09:00
|
|
|
NewLine,
|
2015-06-05 21:30:43 +09:00
|
|
|
Assign,
|
2015-06-06 14:51:45 +09:00
|
|
|
Label,
|
|
|
|
|
Goto,
|
2015-06-06 17:11:02 +09:00
|
|
|
Then,
|
|
|
|
|
Else,
|
|
|
|
|
Endif,
|
2015-06-07 13:28:19 +09:00
|
|
|
For,
|
|
|
|
|
Next,
|
|
|
|
|
Equal,
|
|
|
|
|
NotEqual,
|
|
|
|
|
Less,//<
|
|
|
|
|
Greater,//>
|
|
|
|
|
LessEqual,
|
|
|
|
|
GreaterEqual,
|
2015-06-07 19:11:18 +09:00
|
|
|
LeftShift,//<<
|
|
|
|
|
RightShift,//>>
|
|
|
|
|
LogicalNot,//!
|
|
|
|
|
LogicalAnd,//&&
|
|
|
|
|
LogicalOr,//||
|
|
|
|
|
IntDiv,//DIV
|
2015-06-07 20:56:34 +09:00
|
|
|
Gosub,
|
|
|
|
|
Return,
|
|
|
|
|
End,
|
2015-06-10 19:09:15 +09:00
|
|
|
Break,
|
|
|
|
|
Continue,
|
|
|
|
|
Var,
|
2015-06-11 19:29:34 +09:00
|
|
|
LBracket,//[
|
|
|
|
|
RBracket,//]
|
2015-06-13 19:12:36 +09:00
|
|
|
Def,
|
2015-06-14 11:13:19 +09:00
|
|
|
Out,
|
2015-07-12 12:00:27 +09:00
|
|
|
While,
|
2015-07-12 12:17:01 +09:00
|
|
|
WEnd,
|
2015-07-12 12:47:15 +09:00
|
|
|
Inc,
|
|
|
|
|
Dec,
|
2015-07-13 21:39:42 +09:00
|
|
|
Data,
|
|
|
|
|
Read,
|
|
|
|
|
Restore,
|
2015-08-18 22:50:37 +09:00
|
|
|
On,
|
2015-08-19 11:28:53 +09:00
|
|
|
Input,
|
2015-08-20 15:28:02 +09:00
|
|
|
True,
|
|
|
|
|
False,
|
2016-03-26 19:48:56 +09:00
|
|
|
Use,
|
|
|
|
|
Exec,
|
|
|
|
|
Call,
|
2016-08-31 17:20:12 +09:00
|
|
|
Common,
|
2016-09-02 16:12:23 +09:00
|
|
|
Elseif,
|
2016-09-02 20:39:31 +09:00
|
|
|
Repeat,
|
|
|
|
|
Until,
|
2016-09-03 11:46:11 +09:00
|
|
|
Swap,
|
2016-12-08 21:07:45 +09:00
|
|
|
Dim,
|
2016-12-10 17:24:23 +09:00
|
|
|
Constant,
|
2016-12-29 17:59:47 +09:00
|
|
|
Linput,
|
2017-07-04 20:28:49 +09:00
|
|
|
Stop,
|
2015-06-03 19:51:42 +09:00
|
|
|
}
|
|
|
|
|
|
2016-12-17 11:55:07 +09:00
|
|
|
enum TokenValueType
|
|
|
|
|
{
|
2016-12-17 16:33:39 +09:00
|
|
|
none,
|
2016-12-17 11:55:07 +09:00
|
|
|
integer,
|
|
|
|
|
double_,
|
|
|
|
|
string_
|
|
|
|
|
}
|
|
|
|
|
struct TokenValue
|
|
|
|
|
{
|
|
|
|
|
TokenValueType type;
|
|
|
|
|
private union
|
|
|
|
|
{
|
|
|
|
|
int integer;
|
|
|
|
|
wstring string_;
|
|
|
|
|
double double_;
|
|
|
|
|
}
|
|
|
|
|
ref integerValue()
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.integer);
|
|
|
|
|
return integer;
|
|
|
|
|
}
|
|
|
|
|
int integerValue(int val)
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.integer);
|
|
|
|
|
return integer = val;
|
|
|
|
|
}
|
|
|
|
|
ref stringValue()
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.string_);
|
|
|
|
|
return string_;
|
|
|
|
|
}
|
|
|
|
|
wstring stringValue(wstring val)
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.string_);
|
|
|
|
|
return string_ = val;
|
|
|
|
|
}
|
|
|
|
|
ref doubleValue()
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.double_);
|
|
|
|
|
return double_;
|
|
|
|
|
}
|
|
|
|
|
double doubleValue(double val)
|
|
|
|
|
{
|
|
|
|
|
enforce(type == TokenValueType.double_);
|
|
|
|
|
return double_ = val;
|
|
|
|
|
}
|
|
|
|
|
int castInteger()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.integer:
|
|
|
|
|
return integer;
|
|
|
|
|
case TokenValueType.double_:
|
|
|
|
|
return cast(int)double_;
|
|
|
|
|
default:
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
double castDouble()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.integer:
|
|
|
|
|
return integer;
|
|
|
|
|
case TokenValueType.double_:
|
|
|
|
|
return double_;
|
|
|
|
|
default:
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wstring castString()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.string_:
|
|
|
|
|
return string_;
|
|
|
|
|
default:
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool isNumber()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.integer:
|
|
|
|
|
case TokenValueType.double_:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool isString()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.string_:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this(int v)
|
|
|
|
|
{
|
|
|
|
|
type = TokenValueType.integer;
|
|
|
|
|
integer = v;
|
|
|
|
|
}
|
|
|
|
|
this(wstring v)
|
|
|
|
|
{
|
|
|
|
|
type = TokenValueType.string_;
|
|
|
|
|
string_ = v;
|
|
|
|
|
}
|
|
|
|
|
this(double v)
|
|
|
|
|
{
|
|
|
|
|
type = TokenValueType.double_;
|
|
|
|
|
double_ = v;
|
|
|
|
|
}
|
|
|
|
|
Value toSBImm()
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case TokenValueType.integer:
|
|
|
|
|
return Value(integer);
|
|
|
|
|
case TokenValueType.string_:
|
|
|
|
|
return Value(string_);
|
|
|
|
|
case TokenValueType.double_:
|
|
|
|
|
return Value(double_);
|
|
|
|
|
default:
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 19:51:42 +09:00
|
|
|
struct Token
|
|
|
|
|
{
|
|
|
|
|
TokenType type;
|
2016-12-17 11:55:07 +09:00
|
|
|
TokenValue value;
|
|
|
|
|
this(TokenType t, TokenValue v)
|
2015-06-03 19:51:42 +09:00
|
|
|
{
|
|
|
|
|
type = t;
|
|
|
|
|
value = v;
|
|
|
|
|
}
|
2015-06-03 20:59:47 +09:00
|
|
|
this(TokenType t)
|
|
|
|
|
{
|
|
|
|
|
type = t;
|
|
|
|
|
}
|
2015-06-03 19:51:42 +09:00
|
|
|
}
|
2015-08-30 12:33:54 +09:00
|
|
|
struct SourceLocation
|
|
|
|
|
{
|
|
|
|
|
int line;//何行目
|
|
|
|
|
int pos;//何文字目
|
|
|
|
|
int pos2;//全体から何文字目
|
|
|
|
|
}
|