Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src
diff options
context:
space:
mode:
Commit3ce342b97b6c22b7ce6dded7be7b5c6bf9edcc04 (patch)
Author
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-19 23:49:15 +0200
Committer
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-21 21:20:34 +0200
Files8a6bc5aa0fb2fcc3c9589e53b91bc316141c7cda /spasm/src
IPL-3ce342b97b6c22b7ce6dded7be7b5c6bf9edcc04.tar
IPL-3ce342b97b6c22b7ce6dded7be7b5c6bf9edcc04.tar.gz
IPL-3ce342b97b6c22b7ce6dded7be7b5c6bf9edcc04.zip
Parent36711f22e4d3449d75f8412654330a7ca5c3275a (diff)
Support for doubles in the assembler
8 files changed, 687 insertions, 490 deletions
-rw-r--r--spasm/src/asm/assembler.cpp106
-rw-r--r--spasm/src/asm/bytecode.cpp40
-rw-r--r--spasm/src/asm/bytecode.hpp9
-rw-r--r--spasm/src/asm/lexer.cpp522
-rw-r--r--spasm/src/asm/lexer.re408
-rw-r--r--spasm/src/asm/token.cpp31
-rw-r--r--spasm/src/asm/token.hpp4
-rw-r--r--spasm/src/spasm.cpp57
diff --git a/spasm/src/asm/assembler.cpp b/spasm/src/asm/assembler.cpp
index aad2911..2ec988f 100644
--- a/spasm/src/asm/assembler.cpp
+++ b/spasm/src/asm/assembler.cpp
@@ -14,6 +14,54 @@ Assembler::Assembler(Lexer::Tokenizer& tokenizer, Bytecode_Stream& bytecode)
{
}
+int get_arg_size(const Lexer::Token args[])
+{
+ int size = 0;
+ for (int i = 0; i < 3; ++i)
+ {
+ switch (args[i].type())
+ {
+ case Lexer::Token::Integer:
+ case Lexer::Token::XInteger:
+ {
+ if (args[i].value_int() > 0xffffffff)
+ {
+ size = std::max(size, 3);
+ }
+ else if (args[i].value_int() > 0xffff)
+ {
+ size = std::max(size, 2);
+ }
+ else if (args[i].value_int() > 0xff)
+ {
+ size = std::max(size, 1);
+ }
+ else if (args[i].value_int() < -0xffffffffLL)
+ {
+ size = std::max(size, 3);
+ }
+ else if (args[i].value_int() < -0xffff)
+ {
+ size = std::max(size, 2);
+ }
+ else if (args[i].value_int() < -0xff)
+ {
+ size = std::max(size, 1);
+ }
+ break;
+ }
+ case Lexer::Token::FloatingPoint:
+ {
+ size = std::max(size, 3);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return size;
+}
+
void Assembler::assemble()
{
Lexer::Token token = _tokenizer->next_token();
@@ -39,42 +87,64 @@ void Assembler::assemble()
}
else
{
- _bytecode->push_opcode((Bytecode_Stream::Opcode_t)token.type());
+ Lexer::Token args[3];
if (type >= Lexer::Token::_OneArgBegin)
{
+ args[0] = _tokenizer->next_token();
+ }
+ if (type >= Lexer::Token::_TwoArgBegin)
+ {
+ args[1] = _tokenizer->next_token();
+ }
+ if (type >= Lexer::Token::_ThreeArgBegin)
+ {
+ args[2] = _tokenizer->next_token();
+ }
+ const auto size = get_arg_size(args);
+ _bytecode->push_opcode((Bytecode_Stream::Opcode_t)((size << 6) |
+ token.type()));
+ const auto arg_size = 1 << size;
+
+ if (args[0].type() != Lexer::Token::NotUsed)
+ {
if (type == Lexer::Token::Call || type == Lexer::Token::Jump)
{
- token = _tokenizer->next_token();
- assert(token.type() == Lexer::Token::Ident);
- assemble_identifier(token);
+ assert(args[0].type() == Lexer::Token::Ident);
+ assemble_identifier(args[0]);
}
else
{
- token = _tokenizer->next_token();
- assert(token.type() == Lexer::Token::Integer);
- _bytecode->push_integer(token.value_int());
+ assert(args[0].type() == Lexer::Token::Integer);
+ _bytecode->push_integer(args[0].value_int(), arg_size);
}
}
- if (type >= Lexer::Token::_TwoArgBegin)
+ if (args[1].type() != Lexer::Token::NotUsed)
{
if (type == Lexer::Token::JumpF || type == Lexer::Token::JumpT)
{
- token = _tokenizer->next_token();
- assert(token.type() == Lexer::Token::Ident);
- assemble_identifier(token);
+ assert(args[1].type() == Lexer::Token::Ident);
+ assemble_identifier(args[1]);
}
else
{
- token = _tokenizer->next_token();
- assert(token.type() == Lexer::Token::Integer);
- _bytecode->push_integer(token.value_int());
+ if (args[1].type() == Lexer::Token::Integer)
+ {
+ _bytecode->push_integer(args[1].value_int(), arg_size);
+ }
+ else if (args[1].type() == Lexer::Token::FloatingPoint)
+ {
+ _bytecode->push_double(args[1].value_double());
+ }
+ else
+ {
+ assert(false && "expected a number type");
+ }
}
}
- if (type >= Lexer::Token::_ThreeArgBegin)
+ if (args[2].type() != Lexer::Token::NotUsed)
{
- token = _tokenizer->next_token();
- assert(token.type() == Lexer::Token::Integer);
- _bytecode->push_integer(token.value_int());
+ assert(args[2].type() == Lexer::Token::Integer);
+ _bytecode->push_integer(args[2].value_int(), arg_size);
}
}
diff --git a/spasm/src/asm/bytecode.cpp b/spasm/src/asm/bytecode.cpp
index 39f1de6..ad436ce 100644
--- a/spasm/src/asm/bytecode.cpp
+++ b/spasm/src/asm/bytecode.cpp
@@ -26,17 +26,17 @@ void Bytecode_File::push_opcode(Bytecode_Stream::Opcode_t opcode)
push_byte(opcode);
}
-void Bytecode_File::push_integer(int number)
+void Bytecode_File::push_integer(int number, int size)
{
- if (number <= 0xff)
- {
- push_byte((byte)number);
- }
- else
- {
- for (size_t i = 0; i < sizeof(int); ++i)
- push_byte((number >> (i << 3)) & 0xff);
- }
+ for (int i = 0; i < size; ++i)
+ push_byte((number >> (i << 3)) & 0xff);
+}
+
+void Bytecode_File::push_double(double number)
+{
+ auto bits = *reinterpret_cast<size_t*>(&number);
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ push_byte((bits >> (i << 3)) & 0xff);
}
void Bytecode_Memory::push_byte(Bytecode_Stream::byte byte)
@@ -49,17 +49,17 @@ void Bytecode_Memory::push_opcode(Bytecode_Stream::Opcode_t opcode)
push_byte(opcode);
}
-void Bytecode_Memory::push_integer(int number)
+void Bytecode_Memory::push_integer(int number, int size)
{
- if (number <= 0xff)
- {
- push_byte((byte)number);
- }
- else
- {
- for (size_t i = 0; i < sizeof(int); ++i)
- push_byte((number >> (i << 3)) & 0xff);
- }
+ for (int i = 0; i < size; ++i)
+ push_byte((number >> (i << 3)) & 0xff);
+}
+
+void Bytecode_Memory::push_double(double number)
+{
+ auto bits = *reinterpret_cast<size_t*>(&number);
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ push_byte((bits >> (i << 3)) & 0xff);
}
void Bytecode_Memory::set_location(size_t index, size_t location)
diff --git a/spasm/src/asm/bytecode.hpp b/spasm/src/asm/bytecode.hpp
index 374ccef..345b7a8 100644
--- a/spasm/src/asm/bytecode.hpp
+++ b/spasm/src/asm/bytecode.hpp
@@ -18,7 +18,8 @@ class Bytecode_Stream
virtual ~Bytecode_Stream();
virtual void push_opcode(Opcode_t) = 0;
- virtual void push_integer(int) = 0;
+ virtual void push_integer(int, int size) = 0;
+ virtual void push_double(double) = 0;
virtual void push_location(size_t) = 0;
virtual void set_location(size_t, size_t) = 0;
virtual size_t size() const = 0;
@@ -30,7 +31,8 @@ class Bytecode_File : public Bytecode_Stream
Bytecode_File(const std::string&);
virtual void push_opcode(Opcode_t);
- virtual void push_integer(int);
+ virtual void push_integer(int, int size);
+ virtual void push_double(double) override;
private:
Bytecode_File(const Bytecode_File&);
@@ -45,7 +47,8 @@ class Bytecode_Memory : public Bytecode_Stream
{
public:
virtual void push_opcode(Opcode_t);
- virtual void push_integer(int);
+ virtual void push_integer(int, int) override;
+ virtual void push_double(double) override;
virtual void push_location(size_t);
virtual void set_location(size_t, size_t);
virtual size_t size() const;
diff --git a/spasm/src/asm/lexer.cpp b/spasm/src/asm/lexer.cpp
index 3af83c7..0a51b2f 100644
--- a/spasm/src/asm/lexer.cpp
+++ b/spasm/src/asm/lexer.cpp
@@ -1,4 +1,4 @@
-/* Generated by re2c 1.1.1 on Thu Nov 15 10:01:26 2018 */
+/* Generated by re2c 1.1.1 on Mon Nov 19 23:46:47 2018 */
#line 1 "lexer.re"
#include <iostream>
@@ -41,11 +41,10 @@ bool Lexer::tokenize(TokenStream& ts)
{
case 0x00:
goto yy2;
- case '\t':
- case ' ':
- goto yy6;
case '\n':
- goto yy9;
+ goto yy6;
+ case ' ':
+ goto yy8;
case '-':
goto yy11;
case '0':
@@ -128,52 +127,51 @@ bool Lexer::tokenize(TokenStream& ts)
}
yy2:
++cursor;
-#line 254 "lexer.re"
+#line 264 "lexer.re"
{
ts.push_token(Token(Token::EndInput, lineno));
break;
}
-#line 125 "lexer.cpp"
+#line 124 "lexer.cpp"
yy4:
++cursor;
yy5:
-#line 260 "lexer.re"
+#line 270 "lexer.re"
{
return false;
}
-#line 133 "lexer.cpp"
+#line 132 "lexer.cpp"
yy6:
++cursor;
+#line 257 "lexer.re"
+ {
+ ++lineno;
+ token_start = cursor;
+
+ continue;
+ }
+#line 142 "lexer.cpp"
+ yy8:
+ ++cursor;
if (limit <= cursor)
return true;
yych = *cursor;
switch (yych)
{
- case '\t':
case ' ':
- goto yy6;
- default:
goto yy8;
+ default:
+ goto yy10;
}
- yy8:
-#line 241 "lexer.re"
+ yy10:
+#line 251 "lexer.re"
{
token_start = cursor;
continue;
}
-#line 150 "lexer.cpp"
- yy9:
- ++cursor;
-#line 247 "lexer.re"
- {
- ++lineno;
- token_start = cursor;
-
- continue;
- }
-#line 160 "lexer.cpp"
+#line 158 "lexer.cpp"
yy11:
yych = *++cursor;
switch (yych)
@@ -194,21 +192,23 @@ bool Lexer::tokenize(TokenStream& ts)
goto yy13;
}
yy13:
-#line 59 "lexer.re"
+#line 60 "lexer.re"
{
ts.push_token(Token(Token::Integer, lineno, token_start, cursor));
token_start = cursor;
continue;
}
-#line 183 "lexer.cpp"
+#line 181 "lexer.cpp"
yy14:
- ++cursor;
- if (limit <= cursor)
+ marker = ++cursor;
+ if ((limit - cursor) < 2)
return true;
yych = *cursor;
switch (yych)
{
+ case '.':
+ goto yy31;
case '0':
case '1':
case '2':
@@ -299,20 +299,20 @@ bool Lexer::tokenize(TokenStream& ts)
goto yy18;
}
yy18:
-#line 233 "lexer.re"
+#line 243 "lexer.re"
{
ts.push_token(Token(Token::Ident, lineno, token_start, cursor));
token_start = cursor;
continue;
}
-#line 281 "lexer.cpp"
+#line 280 "lexer.cpp"
yy19:
yych = *++cursor;
switch (yych)
{
case '0':
- goto yy31;
+ goto yy32;
case '1':
case '2':
case '3':
@@ -322,9 +322,9 @@ bool Lexer::tokenize(TokenStream& ts)
case '7':
case '8':
case '9':
- goto yy33;
+ goto yy34;
case 'd':
- goto yy35;
+ goto yy36;
default:
goto yy17;
}
@@ -333,9 +333,9 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'a':
- goto yy36;
- case 'o':
goto yy37;
+ case 'o':
+ goto yy38;
default:
goto yy17;
}
@@ -344,9 +344,9 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'i':
- goto yy38;
- case 'u':
goto yy39;
+ case 'u':
+ goto yy40;
default:
goto yy17;
}
@@ -355,7 +355,7 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'm':
- goto yy40;
+ goto yy41;
default:
goto yy17;
}
@@ -364,9 +364,9 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'a':
- goto yy41;
- case 'e':
goto yy42;
+ case 'e':
+ goto yy43;
default:
goto yy17;
}
@@ -375,9 +375,9 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'o':
- goto yy43;
- case 'u':
goto yy44;
+ case 'u':
+ goto yy45;
default:
goto yy17;
}
@@ -386,11 +386,11 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'o':
- goto yy45;
- case 'r':
goto yy46;
- case 'u':
+ case 'r':
goto yy47;
+ case 'u':
+ goto yy48;
default:
goto yy17;
}
@@ -399,7 +399,7 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case '0':
- goto yy48;
+ goto yy49;
case '1':
case '2':
case '3':
@@ -409,9 +409,9 @@ bool Lexer::tokenize(TokenStream& ts)
case '7':
case '8':
case '9':
- goto yy50;
+ goto yy51;
case 'e':
- goto yy52;
+ goto yy53;
default:
goto yy17;
}
@@ -420,7 +420,7 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case 'u':
- goto yy53;
+ goto yy54;
default:
goto yy17;
}
@@ -453,7 +453,7 @@ bool Lexer::tokenize(TokenStream& ts)
case 'd':
case 'e':
case 'f':
- goto yy54;
+ goto yy55;
default:
goto yy30;
}
@@ -465,6 +465,25 @@ bool Lexer::tokenize(TokenStream& ts)
switch (yych)
{
case '0':
+ goto yy58;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ goto yy60;
+ default:
+ goto yy30;
+ }
+ yy32:
+ yych = *++cursor;
+ switch (yych)
+ {
+ case '0':
case '1':
case '2':
case '3':
@@ -529,10 +548,10 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy32;
+ goto yy33;
}
- yy32:
-#line 74 "lexer.re"
+ yy33:
+#line 84 "lexer.re"
{
Token t(Token::Integer, lineno, token_start + 1, cursor);
t.set_int(-t.value_int());
@@ -540,8 +559,8 @@ bool Lexer::tokenize(TokenStream& ts)
token_start = cursor;
continue;
}
-#line 473 "lexer.cpp"
- yy33:
+#line 487 "lexer.cpp"
+ yy34:
++cursor;
if (limit <= cursor)
return true;
@@ -558,7 +577,7 @@ bool Lexer::tokenize(TokenStream& ts)
case '7':
case '8':
case '9':
- goto yy33;
+ goto yy34;
case 'A':
case 'B':
case 'C':
@@ -614,128 +633,128 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy32;
+ goto yy33;
}
- yy35:
+ yy36:
yych = *++cursor;
switch (yych)
{
case 'd':
- goto yy57;
+ goto yy62;
default:
goto yy17;
}
- yy36:
+ yy37:
yych = *++cursor;
switch (yych)
{
case 'l':
- goto yy59;
+ goto yy64;
default:
goto yy17;
}
- yy37:
+ yy38:
yych = *++cursor;
switch (yych)
{
case 'n':
- goto yy60;
+ goto yy65;
default:
goto yy17;
}
- yy38:
+ yy39:
yych = *++cursor;
switch (yych)
{
case 'v':
- goto yy61;
+ goto yy66;
default:
goto yy17;
}
- yy39:
+ yy40:
yych = *++cursor;
switch (yych)
{
case 'p':
- goto yy63;
+ goto yy68;
default:
goto yy17;
}
- yy40:
+ yy41:
yych = *++cursor;
switch (yych)
{
case 'p':
- goto yy65;
+ goto yy70;
default:
goto yy17;
}
- yy41:
+ yy42:
yych = *++cursor;
switch (yych)
{
case 'b':
- goto yy67;
+ goto yy72;
default:
goto yy17;
}
- yy42:
+ yy43:
yych = *++cursor;
switch (yych)
{
case 'q':
- goto yy68;
+ goto yy73;
case 's':
- goto yy70;
+ goto yy75;
default:
goto yy17;
}
- yy43:
+ yy44:
yych = *++cursor;
switch (yych)
{
case 'd':
- goto yy71;
+ goto yy76;
default:
goto yy17;
}
- yy44:
+ yy45:
yych = *++cursor;
switch (yych)
{
case 'l':
- goto yy73;
+ goto yy78;
default:
goto yy17;
}
- yy45:
+ yy46:
yych = *++cursor;
switch (yych)
{
case 'p':
- goto yy75;
+ goto yy80;
default:
goto yy17;
}
- yy46:
+ yy47:
yych = *++cursor;
switch (yych)
{
case 'i':
- goto yy77;
+ goto yy82;
default:
goto yy17;
}
- yy47:
+ yy48:
yych = *++cursor;
switch (yych)
{
case 's':
- goto yy78;
+ goto yy83;
default:
goto yy17;
}
- yy48:
+ yy49:
yych = *++cursor;
switch (yych)
{
@@ -804,10 +823,10 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy49;
+ goto yy50;
}
- yy49:
-#line 67 "lexer.re"
+ yy50:
+#line 77 "lexer.re"
{
ts.push_token(
Token(Token::Integer, lineno, token_start + 1, cursor));
@@ -815,8 +834,8 @@ bool Lexer::tokenize(TokenStream& ts)
continue;
}
-#line 700 "lexer.cpp"
- yy50:
+#line 714 "lexer.cpp"
+ yy51:
++cursor;
if (limit <= cursor)
return true;
@@ -833,7 +852,7 @@ bool Lexer::tokenize(TokenStream& ts)
case '7':
case '8':
case '9':
- goto yy50;
+ goto yy51;
case 'A':
case 'B':
case 'C':
@@ -889,29 +908,29 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy49;
+ goto yy50;
}
- yy52:
+ yy53:
yych = *++cursor;
switch (yych)
{
case 'a':
- goto yy79;
+ goto yy84;
case 't':
- goto yy80;
+ goto yy85;
default:
goto yy17;
}
- yy53:
+ yy54:
yych = *++cursor;
switch (yych)
{
case 'b':
- goto yy82;
+ goto yy87;
default:
goto yy17;
}
- yy54:
+ yy55:
++cursor;
if (limit <= cursor)
return true;
@@ -940,20 +959,53 @@ bool Lexer::tokenize(TokenStream& ts)
case 'd':
case 'e':
case 'f':
- goto yy54;
+ goto yy55;
default:
- goto yy56;
+ goto yy57;
}
- yy56:
-#line 83 "lexer.re"
+ yy57:
+#line 93 "lexer.re"
{
ts.push_token(Token(Token::XInteger, lineno, token_start, cursor));
token_start = cursor;
continue;
}
-#line 822 "lexer.cpp"
- yy57:
+#line 836 "lexer.cpp"
+ yy58:
+ ++cursor;
+ yy59:
+#line 68 "lexer.re"
+ {
+ ts.push_token(
+ Token(Token::FloatingPoint, lineno, token_start, cursor));
+ token_start = cursor;
+
+ continue;
+ }
+#line 849 "lexer.cpp"
+ yy60:
+ ++cursor;
+ if (limit <= cursor)
+ return true;
+ yych = *cursor;
+ switch (yych)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ goto yy60;
+ default:
+ goto yy59;
+ }
+ yy62:
yych = *++cursor;
switch (yych)
{
@@ -1022,36 +1074,36 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy58;
+ goto yy63;
}
- yy58:
-#line 137 "lexer.re"
+ yy63:
+#line 147 "lexer.re"
{
ts.push_token(Token(Token::Add, lineno));
token_start = cursor;
continue;
}
-#line 899 "lexer.cpp"
- yy59:
+#line 943 "lexer.cpp"
+ yy64:
yych = *++cursor;
switch (yych)
{
case 'l':
- goto yy84;
+ goto yy89;
default:
goto yy17;
}
- yy60:
+ yy65:
yych = *++cursor;
switch (yych)
{
case 's':
- goto yy86;
+ goto yy91;
default:
goto yy17;
}
- yy61:
+ yy66:
yych = *++cursor;
switch (yych)
{
@@ -1120,18 +1172,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy62;
+ goto yy67;
}
- yy62:
-#line 158 "lexer.re"
+ yy67:
+#line 168 "lexer.re"
{
ts.push_token(Token(Token::Div, lineno));
token_start = cursor;
continue;
}
-#line 988 "lexer.cpp"
- yy63:
+#line 1032 "lexer.cpp"
+ yy68:
yych = *++cursor;
switch (yych)
{
@@ -1200,18 +1252,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy64;
+ goto yy69;
}
- yy64:
-#line 116 "lexer.re"
+ yy69:
+#line 126 "lexer.re"
{
ts.push_token(Token(Token::Dup, lineno));
token_start = cursor;
continue;
}
-#line 1065 "lexer.cpp"
- yy65:
+#line 1109 "lexer.cpp"
+ yy70:
yych = *++cursor;
switch (yych)
{
@@ -1278,31 +1330,31 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
case 'f':
- goto yy87;
+ goto yy92;
case 't':
- goto yy89;
+ goto yy94;
default:
- goto yy66;
+ goto yy71;
}
- yy66:
-#line 186 "lexer.re"
+ yy71:
+#line 196 "lexer.re"
{
ts.push_token(Token(Token::Jump, lineno));
token_start = cursor;
continue;
}
-#line 1142 "lexer.cpp"
- yy67:
+#line 1186 "lexer.cpp"
+ yy72:
yych = *++cursor;
switch (yych)
{
case 'e':
- goto yy91;
+ goto yy96;
default:
goto yy17;
}
- yy68:
+ yy73:
yych = *++cursor;
switch (yych)
{
@@ -1371,27 +1423,27 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy69;
+ goto yy74;
}
- yy69:
-#line 213 "lexer.re"
+ yy74:
+#line 223 "lexer.re"
{
ts.push_token(Token(Token::LessEq, lineno));
token_start = cursor;
continue;
}
-#line 1225 "lexer.cpp"
- yy70:
+#line 1269 "lexer.cpp"
+ yy75:
yych = *++cursor;
switch (yych)
{
case 's':
- goto yy92;
+ goto yy97;
default:
goto yy17;
}
- yy71:
+ yy76:
yych = *++cursor;
switch (yych)
{
@@ -1460,18 +1512,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy72;
+ goto yy77;
}
- yy72:
-#line 165 "lexer.re"
+ yy77:
+#line 175 "lexer.re"
{
ts.push_token(Token(Token::Mod, lineno));
token_start = cursor;
continue;
}
-#line 1308 "lexer.cpp"
- yy73:
+#line 1352 "lexer.cpp"
+ yy78:
yych = *++cursor;
switch (yych)
{
@@ -1540,18 +1592,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy74;
+ goto yy79;
}
- yy74:
-#line 151 "lexer.re"
+ yy79:
+#line 161 "lexer.re"
{
ts.push_token(Token(Token::Mul, lineno));
token_start = cursor;
continue;
}
-#line 1385 "lexer.cpp"
- yy75:
+#line 1429 "lexer.cpp"
+ yy80:
yych = *++cursor;
switch (yych)
{
@@ -1619,47 +1671,47 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
case 'r':
- goto yy94;
+ goto yy99;
default:
- goto yy76;
+ goto yy81;
}
- yy76:
-#line 103 "lexer.re"
+ yy81:
+#line 113 "lexer.re"
{
ts.push_token(Token(Token::Pop, lineno));
token_start = cursor;
continue;
}
-#line 1462 "lexer.cpp"
- yy77:
+#line 1506 "lexer.cpp"
+ yy82:
yych = *++cursor;
switch (yych)
{
case 'n':
- goto yy96;
+ goto yy101;
default:
goto yy17;
}
- yy78:
+ yy83:
yych = *++cursor;
switch (yych)
{
case 'h':
- goto yy97;
+ goto yy102;
default:
goto yy17;
}
- yy79:
+ yy84:
yych = *++cursor;
switch (yych)
{
case 'd':
- goto yy99;
+ goto yy104;
default:
goto yy17;
}
- yy80:
+ yy85:
yych = *++cursor;
switch (yych)
{
@@ -1728,18 +1780,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy81;
+ goto yy86;
}
- yy81:
-#line 206 "lexer.re"
+ yy86:
+#line 216 "lexer.re"
{
ts.push_token(Token(Token::Ret, lineno));
token_start = cursor;
continue;
}
-#line 1557 "lexer.cpp"
- yy82:
+#line 1601 "lexer.cpp"
+ yy87:
yych = *++cursor;
switch (yych)
{
@@ -1808,18 +1860,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy83;
+ goto yy88;
}
- yy83:
-#line 144 "lexer.re"
+ yy88:
+#line 154 "lexer.re"
{
ts.push_token(Token(Token::Sub, lineno));
token_start = cursor;
continue;
}
-#line 1634 "lexer.cpp"
- yy84:
+#line 1678 "lexer.cpp"
+ yy89:
yych = *++cursor;
switch (yych)
{
@@ -1888,27 +1940,27 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy85;
+ goto yy90;
}
- yy85:
-#line 199 "lexer.re"
+ yy90:
+#line 209 "lexer.re"
{
ts.push_token(Token(Token::Call, lineno));
token_start = cursor;
continue;
}
-#line 1711 "lexer.cpp"
- yy86:
+#line 1755 "lexer.cpp"
+ yy91:
yych = *++cursor;
switch (yych)
{
case 't':
- goto yy101;
+ goto yy106;
default:
goto yy17;
}
- yy87:
+ yy92:
yych = *++cursor;
switch (yych)
{
@@ -1977,18 +2029,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy88;
+ goto yy93;
}
- yy88:
-#line 179 "lexer.re"
+ yy93:
+#line 189 "lexer.re"
{
ts.push_token(Token(Token::JumpF, lineno));
token_start = cursor;
continue;
}
-#line 1794 "lexer.cpp"
- yy89:
+#line 1838 "lexer.cpp"
+ yy94:
yych = *++cursor;
switch (yych)
{
@@ -2057,27 +2109,27 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy90;
+ goto yy95;
}
- yy90:
-#line 172 "lexer.re"
+ yy95:
+#line 182 "lexer.re"
{
ts.push_token(Token(Token::JumpT, lineno));
token_start = cursor;
continue;
}
-#line 1871 "lexer.cpp"
- yy91:
+#line 1915 "lexer.cpp"
+ yy96:
yych = *++cursor;
switch (yych)
{
case 'l':
- goto yy103;
+ goto yy108;
default:
goto yy17;
}
- yy92:
+ yy97:
yych = *++cursor;
switch (yych)
{
@@ -2146,18 +2198,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy93;
+ goto yy98;
}
- yy93:
-#line 219 "lexer.re"
+ yy98:
+#line 229 "lexer.re"
{
ts.push_token(Token(Token::Less, lineno));
token_start = cursor;
continue;
}
-#line 1954 "lexer.cpp"
- yy94:
+#line 1998 "lexer.cpp"
+ yy99:
yych = *++cursor;
switch (yych)
{
@@ -2226,27 +2278,27 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy95;
+ goto yy100;
}
- yy95:
-#line 109 "lexer.re"
+ yy100:
+#line 119 "lexer.re"
{
ts.push_token(Token(Token::PopTo, lineno));
token_start = cursor;
continue;
}
-#line 2031 "lexer.cpp"
- yy96:
+#line 2075 "lexer.cpp"
+ yy101:
yych = *++cursor;
switch (yych)
{
case 't':
- goto yy105;
+ goto yy110;
default:
goto yy17;
}
- yy97:
+ yy102:
yych = *++cursor;
switch (yych)
{
@@ -2314,20 +2366,20 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
case 'r':
- goto yy107;
+ goto yy112;
default:
- goto yy98;
+ goto yy103;
}
- yy98:
-#line 97 "lexer.re"
+ yy103:
+#line 107 "lexer.re"
{
ts.push_token(Token(Token::Push, lineno));
token_start = cursor;
continue;
}
-#line 2114 "lexer.cpp"
- yy99:
+#line 2158 "lexer.cpp"
+ yy104:
yych = *++cursor;
switch (yych)
{
@@ -2396,18 +2448,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy100;
+ goto yy105;
}
- yy100:
-#line 123 "lexer.re"
+ yy105:
+#line 133 "lexer.re"
{
ts.push_token(Token(Token::Read, lineno));
token_start = cursor;
continue;
}
-#line 2191 "lexer.cpp"
- yy101:
+#line 2235 "lexer.cpp"
+ yy106:
yych = *++cursor;
switch (yych)
{
@@ -2476,18 +2528,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy102;
+ goto yy107;
}
- yy102:
-#line 192 "lexer.re"
+ yy107:
+#line 202 "lexer.re"
{
ts.push_token(Token(Token::Const, lineno));
token_start = cursor;
continue;
}
-#line 2268 "lexer.cpp"
- yy103:
+#line 2312 "lexer.cpp"
+ yy108:
yych = *++cursor;
switch (yych)
{
@@ -2556,18 +2608,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy104;
+ goto yy109;
}
- yy104:
-#line 226 "lexer.re"
+ yy109:
+#line 236 "lexer.re"
{
ts.push_token(Token(Token::Label, lineno));
token_start = cursor;
continue;
}
-#line 2345 "lexer.cpp"
- yy105:
+#line 2389 "lexer.cpp"
+ yy110:
yych = *++cursor;
switch (yych)
{
@@ -2636,18 +2688,18 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy106;
+ goto yy111;
}
- yy106:
-#line 130 "lexer.re"
+ yy111:
+#line 140 "lexer.re"
{
ts.push_token(Token(Token::Print, lineno));
token_start = cursor;
continue;
}
-#line 2422 "lexer.cpp"
- yy107:
+#line 2466 "lexer.cpp"
+ yy112:
yych = *++cursor;
switch (yych)
{
@@ -2716,19 +2768,19 @@ bool Lexer::tokenize(TokenStream& ts)
case 'z':
goto yy16;
default:
- goto yy108;
+ goto yy113;
}
- yy108:
-#line 91 "lexer.re"
+ yy113:
+#line 101 "lexer.re"
{
ts.push_token(Token(Token::PushFrom, lineno));
token_start = cursor;
continue;
}
-#line 2499 "lexer.cpp"
+#line 2543 "lexer.cpp"
}
-#line 264 "lexer.re"
+#line 274 "lexer.re"
}
return true;
}
@@ -2738,7 +2790,7 @@ bool Lexer::tokenize(TokenStream& ts)
** Note the buffer is always filled to the maximum, not just the
** number of bytes neccessary for the lexer to continue.
**
-** \param nbytes - the number of bytes
+** \param nbytes - the number of bytes
*/
void Lexer::buffer_grow(size_t new_size)
diff --git a/spasm/src/asm/lexer.re b/spasm/src/asm/lexer.re
index c182653..4ab16d1 100644
--- a/spasm/src/asm/lexer.re
+++ b/spasm/src/asm/lexer.re
@@ -13,16 +13,16 @@ namespace Lexer
{
Lexer::Lexer (std::istream & _file, size_t _buffer_size)
- : file (&_file), buffer_size (_buffer_size), state (unsigned(-1)),
- lineno (0)
+ : file (&_file), buffer_size (_buffer_size), state (unsigned(-1)),
+ lineno (0)
{
- buffer = new char[buffer_size];
- cursor = limit = marker = token_start = NULL;
+ buffer = new char[buffer_size];
+ cursor = limit = marker = token_start = NULL;
}
Lexer::~Lexer ()
{
- delete [] buffer;
+ delete [] buffer;
}
bool Lexer::tokenize (TokenStream &ts)
@@ -44,285 +44,295 @@ re2c:define:YYSETSTATE:naked=1;
/*!getstate:re2c */
- while (1) {
+ while (1) {
/*!re2c
-DIGIT = [0-9] ;
-XDIGIT = [0-9a-fA-F] ;
+DIGIT = [0-9] ;
+XDIGIT = [0-9a-fA-F] ;
-INTEGER = "-"? "0" | ([1-9] DIGIT*) ;
-NONNEGATIVE = "0" | ([1-9] DIGIT*) ;
-XINTEGER = "0" [xX] XDIGIT+ ;
-IDENTIFIER = [a-zA-Z_] [0-9a-zA-Z_]* ;
+INTEGER = "-"? "0" | ([1-9] DIGIT*) ;
+NONNEGATIVE = "0" | ([1-9] DIGIT*) ;
+XINTEGER = "0" [xX] XDIGIT+ ;
+FLOATING = "-"? "0" | ([1-9] DIGIT*) "." NONNEGATIVE ;
+IDENTIFIER = [a-zA-Z_] [0-9a-zA-Z_]* ;
-INTEGER {
- ts.push_token (Token (Token::Integer, lineno,
- token_start, cursor));
- token_start = cursor;
+INTEGER {
+ ts.push_token (Token (Token::Integer, lineno,
+ token_start, cursor));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"r" NONNEGATIVE {
- ts.push_token (Token (Token::Integer, lineno,
- token_start + 1, cursor));
- token_start = cursor;
+FLOATING {
+ ts.push_token (Token (Token::FloatingPoint,
+ lineno, token_start,
+ cursor));
+ token_start = cursor;
- continue;
- }
-"a" NONNEGATIVE {
- Token t(Token::Integer, lineno,
- token_start + 1, cursor);
- t.set_int(-t.value_int());
- ts.push_token(t);
- token_start = cursor;
- continue;
- }
+ continue;
+ }
-XINTEGER {
- ts.push_token (Token (Token::XInteger, lineno,
- token_start, cursor));
- token_start = cursor;
+"r" NONNEGATIVE {
+ ts.push_token (Token (Token::Integer, lineno,
+ token_start + 1, cursor));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
+"a" NONNEGATIVE {
+ Token t(Token::Integer, lineno,
+ token_start + 1, cursor);
+ t.set_int(-t.value_int());
+ ts.push_token(t);
+ token_start = cursor;
+ continue;
+ }
-"pushr" {
- ts.push_token (Token (Token::PushFrom, lineno));
- token_start = cursor;
+XINTEGER {
+ ts.push_token (Token (Token::XInteger, lineno,
+ token_start, cursor));
+ token_start = cursor;
- continue;
- }
-"push" {
- ts.push_token (Token (Token::Push, lineno));
- token_start = cursor;
+ continue;
+ }
- continue;
- }
-"pop" {
- ts.push_token (Token (Token::Pop, lineno));
- token_start = cursor;
+"pushr" {
+ ts.push_token (Token (Token::PushFrom, lineno));
+ token_start = cursor;
- continue;
- }
-"popr" {
- ts.push_token (Token (Token::PopTo, lineno));
- token_start = cursor;
+ continue;
+ }
+"push" {
+ ts.push_token (Token (Token::Push, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
+"pop" {
+ ts.push_token (Token (Token::Pop, lineno));
+ token_start = cursor;
-"dup" {
- ts.push_token (Token (Token::Dup, lineno));
- token_start = cursor;
+ continue;
+ }
+"popr" {
+ ts.push_token (Token (Token::PopTo, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"read" {
- ts.push_token (Token (Token::Read, lineno));
- token_start = cursor;
+"dup" {
+ ts.push_token (Token (Token::Dup, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"print" {
- ts.push_token (Token (Token::Print, lineno));
- token_start = cursor;
+"read" {
+ ts.push_token (Token (Token::Read, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"add" {
- ts.push_token (Token (Token::Add, lineno));
- token_start = cursor;
+"print" {
+ ts.push_token (Token (Token::Print, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"sub" {
- ts.push_token (Token (Token::Sub, lineno));
- token_start = cursor;
+"add" {
+ ts.push_token (Token (Token::Add, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"mul" {
- ts.push_token (Token (Token::Mul, lineno));
- token_start = cursor;
+"sub" {
+ ts.push_token (Token (Token::Sub, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"div" {
- ts.push_token (Token (Token::Div, lineno));
- token_start = cursor;
+"mul" {
+ ts.push_token (Token (Token::Mul, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"mod" {
- ts.push_token (Token (Token::Mod, lineno));
- token_start = cursor;
+"div" {
+ ts.push_token (Token (Token::Div, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"jmpt" {
- ts.push_token (Token (Token::JumpT, lineno));
- token_start = cursor;
+"mod" {
+ ts.push_token (Token (Token::Mod, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"jmpf" {
- ts.push_token (Token (Token::JumpF, lineno));
- token_start = cursor;
+"jmpt" {
+ ts.push_token (Token (Token::JumpT, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"jmp" {
- ts.push_token (Token (Token::Jump, lineno));
- token_start = cursor;
+"jmpf" {
+ ts.push_token (Token (Token::JumpF, lineno));
+ token_start = cursor;
- continue;
- }
-"const" {
- ts.push_token (Token (Token::Const, lineno));
- token_start = cursor;
+ continue;
+ }
- continue;
- }
+"jmp" {
+ ts.push_token (Token (Token::Jump, lineno));
+ token_start = cursor;
-"call" {
- ts.push_token (Token (Token::Call, lineno));
- token_start = cursor;
+ continue;
+ }
+"const" {
+ ts.push_token (Token (Token::Const, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"ret" {
- ts.push_token (Token (Token::Ret, lineno));
- token_start = cursor;
+"call" {
+ ts.push_token (Token (Token::Call, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"leq" {
- ts.push_token (Token (Token::LessEq, lineno));
- token_start = cursor;
+"ret" {
+ ts.push_token (Token (Token::Ret, lineno));
+ token_start = cursor;
- continue;
- }
-"less" {
- ts.push_token (Token (Token::Less, lineno));
- token_start = cursor;
+ continue;
+ }
- continue;
- }
+"leq" {
+ ts.push_token (Token (Token::LessEq, lineno));
+ token_start = cursor;
-"label" {
- ts.push_token (Token (Token::Label, lineno));
- token_start = cursor;
+ continue;
+ }
+"less" {
+ ts.push_token (Token (Token::Less, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-IDENTIFIER {
- ts.push_token (Token (Token::Ident, lineno, token_start,
- cursor));
- token_start = cursor;
+"label" {
+ ts.push_token (Token (Token::Label, lineno));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-[ ]+ {
- token_start = cursor;
+IDENTIFIER {
+ ts.push_token (Token (Token::Ident, lineno, token_start,
+ cursor));
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"\n" {
- ++lineno;
- token_start = cursor;
+[ ]+ {
+ token_start = cursor;
- continue;
- }
+ continue;
+ }
-"\000" {
- ts.push_token (Token (Token::EndInput, lineno));
+"\n" {
+ ++lineno;
+ token_start = cursor;
- break;
- }
+ continue;
+ }
-[^] {
- return false;
- }
+"\000" {
+ ts.push_token (Token (Token::EndInput, lineno));
+
+ break;
+ }
+
+[^] {
+ return false;
+ }
*/
- }
- return true;
- }
+ }
+ return true;
+ }
/*!
** Fills up the buffer when neccessary.
** Note the buffer is always filled to the maximum, not just the
** number of bytes neccessary for the lexer to continue.
**
-** \param nbytes - the number of bytes
+** \param nbytes - the number of bytes
*/
void Lexer::buffer_grow (size_t new_size)
{
- char *new_buffer = new char[new_size];
+ char *new_buffer = new char[new_size];
- std::copy (buffer, limit, new_buffer);
+ std::copy (buffer, limit, new_buffer);
- token_start = new_buffer + (token_start - buffer);
- cursor = new_buffer + (cursor - buffer);
- limit = new_buffer + new_size;
+ token_start = new_buffer + (token_start - buffer);
+ cursor = new_buffer + (cursor - buffer);
+ limit = new_buffer + new_size;
- buffer_size = new_size;
+ buffer_size = new_size;
- delete [] buffer;
- buffer = new_buffer;
+ delete [] buffer;
+ buffer = new_buffer;
}
void Lexer::read (size_t nbytes)
{
- if (token_start + nbytes > limit) { // we need larger buffer
- buffer_grow (token_start - buffer + nbytes);
- }
+ if (token_start + nbytes > limit) { // we need larger buffer
+ buffer_grow (token_start - buffer + nbytes);
+ }
- std::copy (token_start, limit, buffer);
- cursor -= token_start - buffer;
- char *old_limit = limit - (token_start - buffer);
- token_start = buffer;
+ std::copy (token_start, limit, buffer);
+ cursor -= token_start - buffer;
+ char *old_limit = limit - (token_start - buffer);
+ token_start = buffer;
- file->read (old_limit, limit - old_limit);
- if (file->eof ()) {
- size_t bytes = file->gcount ();
- std::fill (old_limit + bytes, limit, '\0');
- }
+ file->read (old_limit, limit - old_limit);
+ if (file->eof ()) {
+ size_t bytes = file->gcount ();
+ std::fill (old_limit + bytes, limit, '\0');
+ }
}
void Lexer::buffer_init ()
{
- file->read (buffer, buffer_size);
- if (file->eof ()) {
- size_t bytes = file->gcount ();
- std::fill (buffer + bytes, buffer + buffer_size, '\0');
- }
+ file->read (buffer, buffer_size);
+ if (file->eof ()) {
+ size_t bytes = file->gcount ();
+ std::fill (buffer + bytes, buffer + buffer_size, '\0');
+ }
- cursor = marker = token_start = buffer;
- limit = buffer + buffer_size;
+ cursor = marker = token_start = buffer;
+ limit = buffer + buffer_size;
}
-} // namespace Lexer
+} // namespace Lexer
-} // namespace ASM
-} // namespace SpasmImpl
+} // namespace ASM
+} // namespace SpasmImpl
diff --git a/spasm/src/asm/token.cpp b/spasm/src/asm/token.cpp
index 4f298cf..3f8980d 100644
--- a/spasm/src/asm/token.cpp
+++ b/spasm/src/asm/token.cpp
@@ -22,20 +22,33 @@ Token::Token(Token::Token_type type,
const char* end)
: _type(type), _lineno(lineno)
{
- if (_type == Integer || _type == XInteger)
+ switch (_type)
{
- _value_int = strtol(start, NULL, 0);
- }
- else if (_type == Ident)
- {
- if (end)
+ case Integer:
+ case XInteger:
+ {
+ _value_int = strtol(start, NULL, 0);
+ break;
+ }
+ case FloatingPoint:
{
- _value_str = std::string(start, end);
+ _value_double = strtod(start, NULL);
+ break;
}
- else
+ case Ident:
{
- _value_str = std::string(start);
+ if (end)
+ {
+ _value_str = std::string(start, end);
+ }
+ else
+ {
+ _value_str = std::string(start);
+ }
+ break;
}
+ default:
+ break;
}
}
diff --git a/spasm/src/asm/token.hpp b/spasm/src/asm/token.hpp
index 364b315..6c64e89 100644
--- a/spasm/src/asm/token.hpp
+++ b/spasm/src/asm/token.hpp
@@ -45,6 +45,7 @@ class Token
// Register,
Integer,
XInteger,
+ FloatingPoint,
EndInput,
NotUsed
};
@@ -60,6 +61,8 @@ class Token
int value_int() const;
void set_int(int v) { _value_int = v; }
+ double value_double() const { return _value_double; }
+
const std::string& value_str() const;
private:
@@ -68,6 +71,7 @@ class Token
size_t _lineno;
int _value_int;
+ double _value_double;
std::string _value_str;
};
diff --git a/spasm/src/spasm.cpp b/spasm/src/spasm.cpp
index 6e09be9..58fb6d4 100644
--- a/spasm/src/spasm.cpp
+++ b/spasm/src/spasm.cpp
@@ -46,7 +46,6 @@ Spasm::RunResult Spasm::run()
const auto instruction = m_ByteCode[m_PC++];
const auto opcode = OpCodes(instruction & 0x3f);
const auto size = instruction >> 6;
- assert(size == 0 && "no long args yet");
switch (opcode)
{
case OpCodes::Halt:
@@ -281,7 +280,7 @@ void Spasm::divide(reg_t a0, reg_t a1, reg_t a2)
*/
void Spasm::modulus(reg_t a0, reg_t a1, reg_t a2)
{
- set_local(a0, int64_t(get_local(a1)) % int64_t(get_local(a2)));
+ set_local(a0, data_t(int64_t(get_local(a1)) % int64_t(get_local(a2))));
}
/*!
@@ -410,14 +409,60 @@ void Spasm::push_data(data_t data)
reg_t Spasm::read_reg(size_t size)
{
- assert(size == 0);
- return m_ByteCode[m_PC++];
+ switch (size)
+ {
+ case 0:
+ return m_ByteCode[m_PC++];
+ case 1:
+ {
+ auto result = *reinterpret_cast<int16_t*>(&m_ByteCode[0] + m_PC);
+ m_PC += 2;
+ return result;
+ }
+ case 2:
+ {
+ auto result = *reinterpret_cast<int32_t*>(&m_ByteCode[0] + m_PC);
+ m_PC += 4;
+ return result;
+ }
+ case 3:
+ {
+ auto result = *reinterpret_cast<int64_t*>(&m_ByteCode[0] + m_PC);
+ m_PC += 8;
+ return result;
+ }
+ }
+ assert(false && "not reached");
+ return 0;
}
data_t Spasm::read_number(size_t size)
{
- assert(size == 0);
- return m_ByteCode[m_PC++];
+ switch (size)
+ {
+ case 0:
+ return m_ByteCode[m_PC++];
+ case 1:
+ {
+ auto result = *reinterpret_cast<int16_t*>(&m_ByteCode[0] + m_PC);
+ m_PC += 2;
+ return result;
+ }
+ case 2:
+ {
+ auto result = *reinterpret_cast<int32_t*>(&m_ByteCode[0] + m_PC);
+ m_PC += 4;
+ return result;
+ }
+ case 3:
+ {
+ auto result = *reinterpret_cast<double*>(&m_ByteCode[0] + m_PC);
+ m_PC += 8;
+ return result;
+ }
+ }
+ assert(false && "not reached");
+ return 0;
}
} // namespace SpasmImpl