Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src / asm / assembler.cpp
diff options
context:
space:
mode:
Commit4fca8e8e6c1056aed11437c87e9175232b48c8f4 (patch)
Author
 dtrendafilov <trendafilov.dn@gmail.com>
2018-11-22 16:04:22 +0200
Committer
 GitHub <noreply@github.com>
2018-11-22 16:04:22 +0200
Filesbda85506ae253afd73d3ab36d3685b4e5bae3847 /spasm/src/asm/assembler.cpp
IPL-4fca8e8e6c1056aed11437c87e9175232b48c8f4.tar
IPL-4fca8e8e6c1056aed11437c87e9175232b48c8f4.tar.gz
IPL-4fca8e8e6c1056aed11437c87e9175232b48c8f4.zip
Parent75faff8b35b8f9bfa0a00b973e9323c1dc4c614e (diff)
Parentddc50fe944df0a33386a3213c8021f07ac8ffdd9 (diff)
Merge pull request #62 from SofiaCPP/feature/double
Feature/double
1 files changed, 89 insertions, 19 deletions
-rw-r--r--spasm/src/asm/assembler.cpp108
diff --git a/spasm/src/asm/assembler.cpp b/spasm/src/asm/assembler.cpp
index fbe6675..fadd747 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);
}
}
@@ -105,7 +175,7 @@ void Assembler::assemble_identifier(const Lexer::Token& token)
_bytecode->push_location(symbol->definition());
}
-bool compile(std::istream& istr, Bytecode_Memory& bytecode)
+bool compile(std::istream& istr, Bytecode_Stream& bytecode)
{
Lexer::Tokenizer tokenizer(istr);
Assembler assembler(tokenizer, bytecode);