Format with clang
This commit is contained in:
107
.clang-format
Normal file
107
.clang-format
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
Language: Cpp
|
||||
|
||||
DisableFormat: false
|
||||
Standard: Latest
|
||||
BasedOnStyle: WebKit
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
ConstructorInitializerIndentWidth: 1
|
||||
UseTab: Never
|
||||
ColumnLimit: 120
|
||||
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: No
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
|
||||
# Configure each individual brace in BraceWrapping
|
||||
BreakBeforeBraces: Custom
|
||||
# Control of individual brace wrapping cases
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: false
|
||||
AfterControlStatement: Always
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: true
|
||||
|
||||
BreakAfterJavaFieldAnnotations: true
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
Cpp11BracedListStyle: true
|
||||
FixNamespaceComments: false
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Middle
|
||||
# QualifierAlignment: Right # Only supported in clang-format 14+
|
||||
# ReferenceAlignmentStyle: Middle # Only supported in clang-format 14+
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: Never
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
|
||||
# Comments are for developers, they should arrange them
|
||||
ReflowComments: false
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
---
|
||||
9
bin/fibonacci.wasm
Normal file
9
bin/fibonacci.wasm
Normal file
@@ -0,0 +1,9 @@
|
||||
# Get a number from STDIN
|
||||
|
||||
# Clobbers registers
|
||||
get_user_integer:
|
||||
seti [STRING_STORAGE]
|
||||
|
||||
seti %A $0;
|
||||
seti %B $100;
|
||||
int $5;
|
||||
5
compile_flags.txt
Normal file
5
compile_flags.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
-xc++
|
||||
-Wall
|
||||
-Wextra
|
||||
-Iinclude/
|
||||
-std=c++17
|
||||
@@ -2,24 +2,19 @@
|
||||
#include <string>
|
||||
#include <token/token.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Compile
|
||||
{
|
||||
class Compiler
|
||||
{
|
||||
class Compiler {
|
||||
private:
|
||||
std::unordered_map<std::string, std::size_t> jumpLabelLocations;
|
||||
std::vector<std::pair<Token::Token, std::size_t>> unresolvedJumpLabels;
|
||||
|
||||
void InsertAsBytes(
|
||||
Token::Token const & token,
|
||||
std::vector<std::uint8_t> & bytes);
|
||||
void InsertAsBytes(Token::Token const & token, std::vector<std::uint8_t> & bytes);
|
||||
|
||||
public:
|
||||
bool Compile(
|
||||
std::vector<Token::Token> const & tokens,
|
||||
std::vector<std::uint8_t> & bytes);
|
||||
bool Compile(std::vector<Token::Token> const & tokens, std::vector<std::uint8_t> & bytes);
|
||||
};
|
||||
}
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
namespace Compile
|
||||
{
|
||||
class CompilationError
|
||||
{
|
||||
class CompilationError {
|
||||
public:
|
||||
Token::Token errorToken;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
#include <variant>
|
||||
#include <execute/bytecode.hpp>
|
||||
#include <execute/error.hpp>
|
||||
#include <execute/state.hpp>
|
||||
#include <stdexcept>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace Execute
|
||||
@@ -15,8 +15,7 @@ namespace Execute
|
||||
Memory
|
||||
};
|
||||
|
||||
class ArgumentValue
|
||||
{
|
||||
class ArgumentValue {
|
||||
private:
|
||||
ArgumentType type;
|
||||
ArgumentType memoryValueType;
|
||||
@@ -30,8 +29,6 @@ namespace Execute
|
||||
int Read(State & state) const;
|
||||
|
||||
// Returns the size of the argument in bytes
|
||||
std::size_t Parse(
|
||||
std::vector<std::uint8_t> const & memory,
|
||||
std::size_t const pos);
|
||||
std::size_t Parse(std::vector<std::uint8_t> const & memory, std::size_t const pos);
|
||||
};
|
||||
}
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
class RuntimeError
|
||||
{
|
||||
class RuntimeError {
|
||||
protected:
|
||||
std::string message;
|
||||
std::size_t byteLocation;
|
||||
@@ -16,35 +15,28 @@ namespace Execute
|
||||
RuntimeError(std::string const & what, std::size_t const byteLocation);
|
||||
};
|
||||
|
||||
class InterruptIndexOutOfRange : public RuntimeError
|
||||
{
|
||||
class InterruptIndexOutOfRange : public RuntimeError {
|
||||
public:
|
||||
InterruptIndexOutOfRange(std::size_t const location, int const index);
|
||||
};
|
||||
|
||||
class AttemptedWriteToImmediate : public RuntimeError
|
||||
{
|
||||
class AttemptedWriteToImmediate : public RuntimeError {
|
||||
public:
|
||||
AttemptedWriteToImmediate(std::size_t const location);
|
||||
};
|
||||
|
||||
class NonExecutableInstruction : public RuntimeError
|
||||
{
|
||||
class NonExecutableInstruction : public RuntimeError {
|
||||
public:
|
||||
NonExecutableInstruction(std::size_t const location);
|
||||
};
|
||||
|
||||
class NonArgumentByte : public RuntimeError
|
||||
{
|
||||
class NonArgumentByte : public RuntimeError {
|
||||
public:
|
||||
NonArgumentByte(std::size_t const location);
|
||||
};
|
||||
|
||||
class OutOfMemory : public RuntimeError
|
||||
{
|
||||
class OutOfMemory : public RuntimeError {
|
||||
public:
|
||||
OutOfMemory(
|
||||
std::size_t const requiredMemorySize,
|
||||
std::size_t const actualMemorySize);
|
||||
OutOfMemory(std::size_t const requiredMemorySize, std::size_t const actualMemorySize);
|
||||
};
|
||||
}
|
||||
@@ -5,8 +5,5 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
void ExecuteInterrupt(
|
||||
int const id,
|
||||
Execute::Registers & registers,
|
||||
std::vector<std::uint8_t> & memory);
|
||||
void ExecuteInterrupt(int const id, Execute::Registers & registers, std::vector<std::uint8_t> & memory);
|
||||
}
|
||||
@@ -6,20 +6,15 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
class VirtualMachine
|
||||
{
|
||||
class VirtualMachine {
|
||||
private:
|
||||
State state;
|
||||
|
||||
void DoArithmatic(
|
||||
InstructionByte const instruction,
|
||||
std::array<ArgumentValue, 3> & arguments);
|
||||
void DoArithmatic(InstructionByte const instruction, std::array<ArgumentValue, 3> & arguments);
|
||||
void SetInteger(std::array<ArgumentValue, 3> & arguments);
|
||||
void ExecuteJump(std::array<ArgumentValue, 3> & arguments);
|
||||
void ExecuteInterrupt(std::array<ArgumentValue, 3> & arguments);
|
||||
void ExecuteCall(
|
||||
std::array<ArgumentValue, 3> & arguments,
|
||||
std::size_t const returnByte);
|
||||
void ExecuteCall(std::array<ArgumentValue, 3> & arguments, std::size_t const returnByte);
|
||||
void ExecuteReturn();
|
||||
void DoBooleanLogic(
|
||||
InstructionByte const instruction,
|
||||
@@ -35,9 +30,7 @@ namespace Execute
|
||||
void SingleStep();
|
||||
|
||||
void SetMemorySize(std::size_t const size);
|
||||
void LoadCode(
|
||||
std::vector<std::uint8_t> const & byteCode,
|
||||
bool const printDecodedBytes);
|
||||
void LoadCode(std::vector<std::uint8_t> const & byteCode, bool const printDecodedBytes);
|
||||
|
||||
State const & GetState() const;
|
||||
Execute::InstructionByte GetCurrentInstruction() const;
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Preprocessor
|
||||
{
|
||||
class Preprocessor {
|
||||
private:
|
||||
std::vector<std::string> substitutionIdentifiers;
|
||||
std::vector<std::string> substitutionValues;
|
||||
|
||||
void extractComment(std::string & line,
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn);
|
||||
void extractComment(std::string & line, std::size_t const lineNumber, std::size_t const lineColumn);
|
||||
|
||||
void processLine(std::string & line, std::size_t const lineNumber);
|
||||
|
||||
|
||||
@@ -22,8 +22,18 @@ namespace Token
|
||||
Token(TokenType type, bool validness, int const lineNumber, int const lineColumn);
|
||||
Token(TokenType type, std::string const & string, bool validness, int const lineNumber, int const lineColumn);
|
||||
Token(TokenType type, int value, bool validness, int const lineNumber, int const lineColumn);
|
||||
Token(TokenType type, RegisterType const registerType, bool validness, int const lineNumber, int const lineColumn);
|
||||
Token(TokenType type, OperandType const OperandType, bool validness, int const lineNumber, int const lineColumn);
|
||||
Token(
|
||||
TokenType type,
|
||||
RegisterType const registerType,
|
||||
bool validness,
|
||||
int const lineNumber,
|
||||
int const lineColumn);
|
||||
Token(
|
||||
TokenType type,
|
||||
OperandType const OperandType,
|
||||
bool validness,
|
||||
int const lineNumber,
|
||||
int const lineColumn);
|
||||
|
||||
public:
|
||||
int const lineNumber;
|
||||
@@ -37,7 +47,8 @@ namespace Token
|
||||
Token(Token const & other);
|
||||
|
||||
static Token CreateEmptyToken(int const lineNumber, int const lineColumn);
|
||||
static Token CreateErrorToken(std::string const & message, TokenType const type, int const lineNumber, int const lineColumn);
|
||||
static Token
|
||||
CreateErrorToken(std::string const & message, TokenType const type, int const lineNumber, int const lineColumn);
|
||||
static Token CreateStatementEndToken(int const lineNumber, int const lineColumn);
|
||||
static Token CreateLabelDefinitionToken(std::string const & string, int const lineNumber, int const lineColumn);
|
||||
static Token CreateLabelArgumentToken(std::string const & string, int const lineNumber, int const lineColumn);
|
||||
|
||||
@@ -5,19 +5,13 @@
|
||||
|
||||
namespace Token
|
||||
{
|
||||
class Tokenizer
|
||||
{
|
||||
class Tokenizer {
|
||||
private:
|
||||
// Argument for string should never be of length zero
|
||||
Token ExtractToken(
|
||||
std::string const & string,
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn) const;
|
||||
Token
|
||||
ExtractToken(std::string const & string, std::size_t const lineNumber, std::size_t const lineColumn) const;
|
||||
|
||||
public:
|
||||
void Tokenize(
|
||||
std::string const & line,
|
||||
std::size_t const lineNumber,
|
||||
std::vector<Token> & tokens);
|
||||
void Tokenize(std::string const & line, std::size_t const lineNumber, std::vector<Token> & tokens);
|
||||
};
|
||||
}
|
||||
@@ -9,21 +9,14 @@ namespace Utils
|
||||
bool isWhitespaceCharacter(char const c);
|
||||
|
||||
// Returns nullopt in case the value is missing its terminator character
|
||||
std::optional<std::string> getValueSurroundedBy(
|
||||
std::string const & src,
|
||||
std::size_t const pos,
|
||||
char const surroundingCharacter);
|
||||
std::optional<std::string>
|
||||
getValueSurroundedBy(std::string const & src, std::size_t const pos, char const surroundingCharacter);
|
||||
|
||||
std::string getValueSurroundedByWhitespace(
|
||||
std::string const & src,
|
||||
std::size_t const pos);
|
||||
std::string getValueSurroundedByWhitespace(std::string const & src, std::size_t const pos);
|
||||
|
||||
namespace Bytes
|
||||
{
|
||||
void Write(
|
||||
int const value,
|
||||
std::vector<std::uint8_t> & vec,
|
||||
std::size_t const pos);
|
||||
void Write(int const value, std::vector<std::uint8_t> & vec, std::size_t const pos);
|
||||
|
||||
int Read(std::vector<std::uint8_t> const & vec, std::size_t const pos);
|
||||
}
|
||||
|
||||
@@ -3,30 +3,23 @@
|
||||
#include <execute/virtualmachine.hpp>
|
||||
#include <token/tokenizer.hpp>
|
||||
|
||||
class Wassembler
|
||||
{
|
||||
class Wassembler {
|
||||
private:
|
||||
Execute::VirtualMachine vm;
|
||||
bool printSubstitutions;
|
||||
bool printTokens;
|
||||
bool printTranslatedBytes;
|
||||
|
||||
bool LoadTextFile(
|
||||
std::string const & filePath,
|
||||
std::vector<std::string> & lines) const;
|
||||
bool LoadTextFile(std::string const & filePath, std::vector<std::string> & lines) const;
|
||||
bool Preprocess(std::vector<std::string> & lines) const;
|
||||
bool Tokenize(
|
||||
std::vector<std::string> const & lines,
|
||||
std::vector<Token::Token> & tokens) const;
|
||||
bool Tokenize(std::vector<std::string> const & lines, std::vector<Token::Token> & tokens) const;
|
||||
bool CompileToBytes(
|
||||
std::vector<Token::Token> const & tokens,
|
||||
std::vector<std::string> const & lines,
|
||||
std::vector<std::uint8_t> & bytes) const;
|
||||
void ExecuteCode(std::vector<std::uint8_t> const & bytes);
|
||||
|
||||
bool CompileFile(
|
||||
std::string const & filePath,
|
||||
std::vector<std::uint8_t> & bytes) const;
|
||||
bool CompileFile(std::string const & filePath, std::vector<std::uint8_t> & bytes) const;
|
||||
|
||||
public:
|
||||
void SetMemorySize(unsigned const size);
|
||||
@@ -36,9 +29,7 @@ public:
|
||||
void EnableByteTranslationLogging();
|
||||
|
||||
bool CompileAndRun(std::string const & filePath);
|
||||
bool CompileToFile(
|
||||
std::string const & inputFilePath,
|
||||
std::string const & outputFilePath);
|
||||
bool CompileToFile(std::string const & inputFilePath, std::string const & outputFilePath);
|
||||
|
||||
Wassembler() = default;
|
||||
};
|
||||
4
makefile
4
makefile
@@ -1,6 +1,6 @@
|
||||
CC = g++
|
||||
CFLAGS = -g -std=c++17 -Wall -Iinclude #-Werror
|
||||
LFLAGS = #-lsfml-graphics -lsfml-window -lsfml-system
|
||||
CFLAGS = -g -std=c++17 -Wall -Wextra -Iinclude
|
||||
LFLAGS =
|
||||
|
||||
CPPS = $(shell find src/ -name '*.cpp')
|
||||
OBJS = $(patsubst src/%.cpp, build/%.o, ${CPPS})
|
||||
|
||||
@@ -32,7 +32,9 @@ namespace Compile
|
||||
return 1;
|
||||
|
||||
default:
|
||||
std::printf("WARNING: returning default argument length of 0 for operand type %i\n", static_cast<int>(type));
|
||||
std::printf(
|
||||
"WARNING: returning default argument length of 0 for operand type %i\n",
|
||||
static_cast<int>(type));
|
||||
case Token::OperandType::ReturnFromFunction:
|
||||
case Token::OperandType::ExitProgram:
|
||||
return 0;
|
||||
@@ -41,31 +43,22 @@ namespace Compile
|
||||
|
||||
bool IsArgumentToken(Token::Token const & t)
|
||||
{
|
||||
return
|
||||
t.type == Token::TokenType::ImmediateInteger ||
|
||||
t.type == Token::TokenType::Register ||
|
||||
t.type == Token::TokenType::LabelArgument ||
|
||||
t.type == Token::TokenType::Memory;
|
||||
return t.type == Token::TokenType::ImmediateInteger || t.type == Token::TokenType::Register
|
||||
|| t.type == Token::TokenType::LabelArgument || t.type == Token::TokenType::Memory;
|
||||
}
|
||||
|
||||
bool IsReadableToken(Token::Token const & t)
|
||||
{
|
||||
return
|
||||
t.type == Token::TokenType::ImmediateInteger ||
|
||||
t.type == Token::TokenType::Register ||
|
||||
t.type == Token::TokenType::Memory;
|
||||
return t.type == Token::TokenType::ImmediateInteger || t.type == Token::TokenType::Register
|
||||
|| t.type == Token::TokenType::Memory;
|
||||
}
|
||||
|
||||
bool IsWriteableToken(Token::Token const & t)
|
||||
{
|
||||
return
|
||||
t.type == Token::TokenType::Register ||
|
||||
t.type == Token::TokenType::Memory;
|
||||
return t.type == Token::TokenType::Register || t.type == Token::TokenType::Memory;
|
||||
}
|
||||
|
||||
void ValidateArguments(
|
||||
std::vector<Token::Token> const & tokens,
|
||||
std::size_t const operandIndex)
|
||||
void ValidateArguments(std::vector<Token::Token> const & tokens, std::size_t const operandIndex)
|
||||
{
|
||||
auto const operandType = std::get<Token::OperandType>(tokens[operandIndex].data);
|
||||
switch(operandType)
|
||||
@@ -158,9 +151,7 @@ namespace Compile
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::InsertAsBytes(
|
||||
Token::Token const & token,
|
||||
std::vector<std::uint8_t> & bytes)
|
||||
void Compiler::InsertAsBytes(Token::Token const & token, std::vector<std::uint8_t> & bytes)
|
||||
{
|
||||
switch(token.type)
|
||||
{
|
||||
@@ -256,7 +247,8 @@ namespace Compile
|
||||
|
||||
case Token::TokenType::Register:
|
||||
bytes.push_back(static_cast<std::uint8_t>(Execute::InstructionByte::REGISTER));
|
||||
bytes.push_back(static_cast<std::uint8_t>(GetByteCodeRegister(std::get<Token::RegisterType>(token.data))));
|
||||
bytes.push_back(
|
||||
static_cast<std::uint8_t>(GetByteCodeRegister(std::get<Token::RegisterType>(token.data))));
|
||||
break;
|
||||
|
||||
case Token::TokenType::StatementEnd:
|
||||
@@ -292,7 +284,8 @@ namespace Compile
|
||||
{
|
||||
case Token::TokenValueType::Register:
|
||||
bytes.push_back(static_cast<std::uint8_t>(Execute::InstructionByte::REGISTER));
|
||||
bytes.push_back(static_cast<std::uint8_t>(GetByteCodeRegister(std::get<Token::RegisterType>(token.data))));
|
||||
bytes.push_back(
|
||||
static_cast<std::uint8_t>(GetByteCodeRegister(std::get<Token::RegisterType>(token.data))));
|
||||
break;
|
||||
|
||||
case Token::TokenValueType::Integer:
|
||||
@@ -315,9 +308,7 @@ namespace Compile
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::Compile(
|
||||
std::vector<Token::Token> const & tokens,
|
||||
std::vector<std::uint8_t> & bytes)
|
||||
bool Compiler::Compile(std::vector<Token::Token> const & tokens, std::vector<std::uint8_t> & bytes)
|
||||
{
|
||||
jumpLabelLocations.clear();
|
||||
unresolvedJumpLabels.clear();
|
||||
@@ -406,9 +397,7 @@ namespace Compile
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertAsBytes(
|
||||
token,
|
||||
bytes);
|
||||
InsertAsBytes(token, bytes);
|
||||
state = State::FindOperand;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
|
||||
namespace Compile
|
||||
{
|
||||
CompilationError::CompilationError(
|
||||
std::string const & message,
|
||||
Token::Token const & token)
|
||||
: errorToken(token)
|
||||
CompilationError::CompilationError(std::string const & message, Token::Token const & token) : errorToken(token)
|
||||
{
|
||||
errorToken.errorMessage = message;
|
||||
}
|
||||
|
||||
@@ -94,9 +94,7 @@ namespace Execute
|
||||
}
|
||||
|
||||
// Returns the size of the argument in bytes
|
||||
std::size_t ArgumentValue::Parse(
|
||||
std::vector<std::uint8_t> const & memory,
|
||||
std::size_t const pos)
|
||||
std::size_t ArgumentValue::Parse(std::vector<std::uint8_t> const & memory, std::size_t const pos)
|
||||
{
|
||||
InstructionByte const valueByte = static_cast<InstructionByte>(memory[pos]);
|
||||
switch(valueByte)
|
||||
|
||||
@@ -2,23 +2,13 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::string const & RuntimeError::GetMessage() const
|
||||
{
|
||||
return message;
|
||||
}
|
||||
std::string const & RuntimeError::GetMessage() const { return message; }
|
||||
|
||||
RuntimeError::RuntimeError()
|
||||
: message("Undocumented runtime error")
|
||||
{
|
||||
}
|
||||
RuntimeError::RuntimeError() : message("Undocumented runtime error") { }
|
||||
|
||||
RuntimeError::RuntimeError(
|
||||
std::string const & what,
|
||||
std::size_t const _byteLocation)
|
||||
: message(what),
|
||||
byteLocation(_byteLocation)
|
||||
{
|
||||
}
|
||||
RuntimeError::RuntimeError(std::string const & what, std::size_t const _byteLocation)
|
||||
: message(what), byteLocation(_byteLocation)
|
||||
{ }
|
||||
|
||||
InterruptIndexOutOfRange::InterruptIndexOutOfRange(std::size_t const location, int const index)
|
||||
: RuntimeError("", location)
|
||||
@@ -30,32 +20,27 @@ namespace Execute
|
||||
message += " is out of range";
|
||||
}
|
||||
|
||||
AttemptedWriteToImmediate::AttemptedWriteToImmediate(std::size_t const location)
|
||||
: RuntimeError("", location)
|
||||
AttemptedWriteToImmediate::AttemptedWriteToImmediate(std::size_t const location) : RuntimeError("", location)
|
||||
{
|
||||
message = "Instruction at ";
|
||||
message += std::to_string(location);
|
||||
message += " attempted to write to an immediate value";
|
||||
}
|
||||
|
||||
NonExecutableInstruction::NonExecutableInstruction(std::size_t const location)
|
||||
: RuntimeError("", location)
|
||||
NonExecutableInstruction::NonExecutableInstruction(std::size_t const location) : RuntimeError("", location)
|
||||
{
|
||||
message = "Attempted to execute byte at ";
|
||||
message += std::to_string(location);
|
||||
message += " which is not an instruction byte";
|
||||
}
|
||||
|
||||
NonArgumentByte::NonArgumentByte(std::size_t const location)
|
||||
: RuntimeError("", location)
|
||||
NonArgumentByte::NonArgumentByte(std::size_t const location) : RuntimeError("", location)
|
||||
{
|
||||
message = "Expected an argument byte (immediate, register or memory location) at ";
|
||||
message += std::to_string(location);
|
||||
}
|
||||
|
||||
OutOfMemory::OutOfMemory(
|
||||
std::size_t const requiredMemorySize,
|
||||
std::size_t const actualMemorySize)
|
||||
OutOfMemory::OutOfMemory(std::size_t const requiredMemorySize, std::size_t const actualMemorySize)
|
||||
{
|
||||
message = "Not enough memory to fit code. Actual size is ";
|
||||
message += std::to_string(actualMemorySize);
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
void ExecuteInterrupt(
|
||||
int const id,
|
||||
Execute::Registers & registers,
|
||||
std::vector<std::uint8_t> & memory)
|
||||
void ExecuteInterrupt(int const id, Execute::Registers & registers, std::vector<std::uint8_t> & memory)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
@@ -45,7 +42,8 @@ namespace Execute
|
||||
return;
|
||||
}
|
||||
|
||||
while(std::getchar() != '\n');
|
||||
while(std::getchar() != '\n')
|
||||
;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -81,7 +79,8 @@ namespace Execute
|
||||
|
||||
if(!newlineRead)
|
||||
{
|
||||
while(std::getchar() != '\n');
|
||||
while(std::getchar() != '\n')
|
||||
;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -53,9 +53,7 @@ namespace Execute
|
||||
return memoryOffset - memoryPos;
|
||||
}
|
||||
|
||||
void VirtualMachine::DoArithmatic(
|
||||
InstructionByte const instruction,
|
||||
std::array<ArgumentValue, 3> & arguments)
|
||||
void VirtualMachine::DoArithmatic(InstructionByte const instruction, std::array<ArgumentValue, 3> & arguments)
|
||||
{
|
||||
switch(instruction)
|
||||
{
|
||||
@@ -104,9 +102,7 @@ namespace Execute
|
||||
Execute::ExecuteInterrupt(interruptNo, state.registers, state.memory);
|
||||
}
|
||||
|
||||
void VirtualMachine::ExecuteCall(
|
||||
std::array<ArgumentValue, 3> & arguments,
|
||||
std::size_t const returnByte)
|
||||
void VirtualMachine::ExecuteCall(std::array<ArgumentValue, 3> & arguments, std::size_t const returnByte)
|
||||
{
|
||||
state.PushToStack(returnByte);
|
||||
state.registers.programCounter = arguments[0].Read(state);
|
||||
@@ -171,8 +167,7 @@ namespace Execute
|
||||
// Default to 1 byte (= 1 instruction)
|
||||
std::size_t programCounterIncrement = 1;
|
||||
std::array<ArgumentValue, 3> arguments;
|
||||
InstructionByte const instruction =
|
||||
static_cast<InstructionByte>(state.memory[state.registers.programCounter]);
|
||||
InstructionByte const instruction = static_cast<InstructionByte>(state.memory[state.registers.programCounter]);
|
||||
switch(instruction)
|
||||
{
|
||||
case InstructionByte::ADD_INTEGER:
|
||||
@@ -181,50 +176,34 @@ namespace Execute
|
||||
case InstructionByte::MULTIPLY_INTEGER:
|
||||
case InstructionByte::SHIFT_LEFT_INTEGER:
|
||||
case InstructionByte::SHIFT_RIGHT_INTEGER:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
DoArithmatic(instruction, arguments);
|
||||
state.registers.programCounter += programCounterIncrement;
|
||||
break;
|
||||
|
||||
case InstructionByte::SET_INTEGER:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
SetInteger(arguments);
|
||||
state.registers.programCounter += programCounterIncrement;
|
||||
break;
|
||||
|
||||
case InstructionByte::JUMP:
|
||||
GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
ExecuteJump(arguments);
|
||||
break;
|
||||
|
||||
case InstructionByte::INTERRUPT:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
ExecuteInterrupt(arguments);
|
||||
state.registers.programCounter += programCounterIncrement;
|
||||
break;
|
||||
|
||||
case InstructionByte::CALL:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
ExecuteCall(arguments, state.registers.programCounter + programCounterIncrement);
|
||||
break;
|
||||
|
||||
@@ -239,33 +218,21 @@ namespace Execute
|
||||
case InstructionByte::LESS_THAN_INTEGER:
|
||||
case InstructionByte::GREATER_THAN_INTEGER:
|
||||
case InstructionByte::EQUALS_INTEGER:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
DoBooleanLogic(
|
||||
instruction,
|
||||
arguments,
|
||||
state.registers.programCounter + programCounterIncrement);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
DoBooleanLogic(instruction, arguments, state.registers.programCounter + programCounterIncrement);
|
||||
break;
|
||||
|
||||
case InstructionByte::POP_INTEGER:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
ExecutePop(arguments);
|
||||
state.registers.programCounter += programCounterIncrement;
|
||||
break;
|
||||
|
||||
case InstructionByte::PUSH_INTEGER:
|
||||
programCounterIncrement += GetArguments(
|
||||
instruction,
|
||||
arguments,
|
||||
state.memory,
|
||||
state.registers.programCounter + 1);
|
||||
programCounterIncrement
|
||||
+= GetArguments(instruction, arguments, state.memory, state.registers.programCounter + 1);
|
||||
ExecutePush(arguments);
|
||||
state.registers.programCounter += programCounterIncrement;
|
||||
break;
|
||||
@@ -410,14 +377,9 @@ namespace Execute
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualMachine::SetMemorySize(std::size_t const size)
|
||||
{
|
||||
state.memory.resize(size);
|
||||
}
|
||||
void VirtualMachine::SetMemorySize(std::size_t const size) { state.memory.resize(size); }
|
||||
|
||||
void VirtualMachine::LoadCode(
|
||||
std::vector<std::uint8_t> const & byteCode,
|
||||
bool const printDecodedBytes)
|
||||
void VirtualMachine::LoadCode(std::vector<std::uint8_t> const & byteCode, bool const printDecodedBytes)
|
||||
{
|
||||
if(printDecodedBytes)
|
||||
{
|
||||
|
||||
19
src/main.cpp
19
src/main.cpp
@@ -11,20 +11,15 @@ int main(int argc, char ** argv)
|
||||
bool execute = false, compile = false;
|
||||
std::string outputFile("program.bin");
|
||||
|
||||
auto cli = (
|
||||
clipp::value("input file (*.wasm or *.bin)").set(inputFile),
|
||||
(
|
||||
clipp::required("-e", "--execute").set(execute),
|
||||
auto cli
|
||||
= (clipp::value("input file (*.wasm or *.bin)").set(inputFile),
|
||||
(clipp::required("-e", "--execute").set(execute),
|
||||
clipp::option("-m", "--memory-size") & clipp::value("memory size in bytes (defaults to 4096)", memorySize),
|
||||
clipp::option("-pb", "--print-bytes").set(printBytes)
|
||||
) |
|
||||
(
|
||||
clipp::required("-c", "--compile").set(compile),
|
||||
clipp::option("-o", "--output-file") & clipp::value("output file", outputFile)
|
||||
),
|
||||
clipp::option("-pb", "--print-bytes").set(printBytes))
|
||||
| (clipp::required("-c", "--compile").set(compile),
|
||||
clipp::option("-o", "--output-file") & clipp::value("output file", outputFile)),
|
||||
clipp::option("-ps", "--print-substitutions").set(printSubstitutions),
|
||||
clipp::option("-pt", "--print-tokens").set(printTokens)
|
||||
);
|
||||
clipp::option("-pt", "--print-tokens").set(printTokens));
|
||||
|
||||
if(!clipp::parse(argc, argv, cli))
|
||||
{
|
||||
|
||||
@@ -27,13 +27,9 @@ bool trySubstitute(
|
||||
return false;
|
||||
}
|
||||
|
||||
void Preprocessor::extractComment(
|
||||
std::string & line,
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn)
|
||||
void Preprocessor::extractComment(std::string & line, std::size_t const lineNumber, std::size_t const lineColumn)
|
||||
{
|
||||
if (line.size() <= lineColumn + 1 ||
|
||||
line.compare(lineColumn + 1, std::string::npos, "DEFINE") <= 0)
|
||||
if(line.size() <= lineColumn + 1 || line.compare(lineColumn + 1, std::string::npos, "DEFINE") <= 0)
|
||||
{
|
||||
// No match or empty DEFINE statement
|
||||
line = line.substr(0, lineColumn);
|
||||
@@ -151,9 +147,6 @@ void Preprocessor::printSubstitutions() const
|
||||
{
|
||||
for(std::size_t i = 0; i < substitutionIdentifiers.size(); ++i)
|
||||
{
|
||||
std::printf(
|
||||
"%s -> %s\n",
|
||||
substitutionIdentifiers[i].c_str(),
|
||||
substitutionValues[i].c_str());
|
||||
std::printf("%s -> %s\n", substitutionIdentifiers[i].c_str(), substitutionValues[i].c_str());
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
namespace Token
|
||||
{
|
||||
TokenizationError::TokenizationError(Token const & token, std::string const & msg)
|
||||
: errorToken(token),
|
||||
errorMsg(msg)
|
||||
{
|
||||
}
|
||||
: errorToken(token), errorMsg(msg)
|
||||
{ }
|
||||
}
|
||||
@@ -5,8 +5,7 @@ namespace Token
|
||||
{
|
||||
OperandType GetOperandType(std::string const & op)
|
||||
{
|
||||
static std::map<std::string, OperandType, std::less<>> const operations =
|
||||
{
|
||||
static std::map<std::string, OperandType, std::less<>> const operations = {
|
||||
{"addi", OperandType::AddInteger},
|
||||
{"subi", OperandType::SubtractInteger},
|
||||
{"divi", OperandType::DivideInteger},
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
#include <token/registertype.hpp>
|
||||
#include <map>
|
||||
#include <token/registertype.hpp>
|
||||
|
||||
namespace Token
|
||||
{
|
||||
RegisterType GetRegisterType(std::string const & reg)
|
||||
{
|
||||
static std::map<std::string, RegisterType, std::less<>> const registers =
|
||||
{
|
||||
{ "A", RegisterType::A },
|
||||
{ "B", RegisterType::B },
|
||||
{ "C", RegisterType::C },
|
||||
{ "D", RegisterType::D }
|
||||
};
|
||||
static std::map<std::string, RegisterType, std::less<>> const registers
|
||||
= {{"A", RegisterType::A}, {"B", RegisterType::B}, {"C", RegisterType::C}, {"D", RegisterType::D}};
|
||||
|
||||
auto const & result = registers.find(reg);
|
||||
if(result != registers.end())
|
||||
|
||||
@@ -4,77 +4,60 @@
|
||||
namespace Token
|
||||
{
|
||||
Token::Token(TokenType _type, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(_type),
|
||||
valueType(TokenValueType::None),
|
||||
isValid(validness),
|
||||
data(0),
|
||||
errorMessage()
|
||||
{
|
||||
}
|
||||
: lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::None),
|
||||
isValid(validness), data(0), errorMessage()
|
||||
{ }
|
||||
|
||||
Token::Token(TokenType _type, std::string const & string, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(_type),
|
||||
valueType(TokenValueType::String),
|
||||
isValid(validness),
|
||||
data(string),
|
||||
errorMessage()
|
||||
{
|
||||
}
|
||||
Token::Token(
|
||||
TokenType _type,
|
||||
std::string const & string,
|
||||
bool validness,
|
||||
int const _lineNumber,
|
||||
int const _lineColumn)
|
||||
: lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::String),
|
||||
isValid(validness), data(string), errorMessage()
|
||||
{ }
|
||||
|
||||
Token::Token(TokenType _type, int value, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(_type),
|
||||
valueType(TokenValueType::Integer),
|
||||
isValid(validness),
|
||||
data(value),
|
||||
errorMessage()
|
||||
{
|
||||
}
|
||||
: lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Integer),
|
||||
isValid(validness), data(value), errorMessage()
|
||||
{ }
|
||||
|
||||
Token::Token(TokenType _type, RegisterType const registerType, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(_type),
|
||||
valueType(TokenValueType::Register),
|
||||
isValid(validness),
|
||||
data(registerType),
|
||||
errorMessage()
|
||||
{
|
||||
}
|
||||
Token::Token(
|
||||
TokenType _type,
|
||||
RegisterType const registerType,
|
||||
bool validness,
|
||||
int const _lineNumber,
|
||||
int const _lineColumn)
|
||||
: lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Register),
|
||||
isValid(validness), data(registerType), errorMessage()
|
||||
{ }
|
||||
|
||||
Token::Token(TokenType _type, OperandType const operandType, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(_type),
|
||||
valueType(TokenValueType::Operand),
|
||||
isValid(validness),
|
||||
data(operandType),
|
||||
errorMessage()
|
||||
{
|
||||
}
|
||||
Token::Token(
|
||||
TokenType _type,
|
||||
OperandType const operandType,
|
||||
bool validness,
|
||||
int const _lineNumber,
|
||||
int const _lineColumn)
|
||||
: lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Operand),
|
||||
isValid(validness), data(operandType), errorMessage()
|
||||
{ }
|
||||
|
||||
Token::Token(Token const & other)
|
||||
: lineNumber(other.lineNumber),
|
||||
lineColumn(other.lineColumn),
|
||||
type(other.type),
|
||||
valueType(other.valueType),
|
||||
isValid(other.isValid),
|
||||
data(other.data),
|
||||
errorMessage(other.errorMessage)
|
||||
{
|
||||
}
|
||||
: lineNumber(other.lineNumber), lineColumn(other.lineColumn), type(other.type), valueType(other.valueType),
|
||||
isValid(other.isValid), data(other.data), errorMessage(other.errorMessage)
|
||||
{ }
|
||||
|
||||
Token Token::CreateEmptyToken(int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::Unknown, false, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
Token Token::CreateErrorToken(std::string const & message, TokenType const type, int const lineNumber, int const lineColumn)
|
||||
Token Token::CreateErrorToken(
|
||||
std::string const & message,
|
||||
TokenType const type,
|
||||
int const lineNumber,
|
||||
int const lineColumn)
|
||||
{
|
||||
Token token(type, false, lineNumber, lineColumn);
|
||||
token.errorMessage = message;
|
||||
|
||||
@@ -20,10 +20,8 @@ namespace Token
|
||||
}
|
||||
}
|
||||
|
||||
Token GetCharacterLiteralToken(
|
||||
std::string const & token,
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn)
|
||||
Token
|
||||
GetCharacterLiteralToken(std::string const & token, std::size_t const lineNumber, std::size_t const lineColumn)
|
||||
{
|
||||
for(std::size_t i = 1; i < token.size(); ++i)
|
||||
{
|
||||
@@ -39,10 +37,7 @@ namespace Token
|
||||
}
|
||||
else
|
||||
{
|
||||
return Token::CreateImmediateValueToken(
|
||||
token[1],
|
||||
lineNumber,
|
||||
lineColumn + 1);
|
||||
return Token::CreateImmediateValueToken(token[1], lineNumber, lineColumn + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,10 +49,7 @@ namespace Token
|
||||
lineColumn);
|
||||
}
|
||||
|
||||
Token GetMemoryToken(
|
||||
std::string const & token,
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn)
|
||||
Token GetMemoryToken(std::string const & token, std::size_t const lineNumber, std::size_t const lineColumn)
|
||||
{
|
||||
// Minimal example: [$1] or [%A]
|
||||
if(token.size() < 4)
|
||||
@@ -86,10 +78,7 @@ namespace Token
|
||||
|
||||
if(result.has_value())
|
||||
{
|
||||
return Token::CreateMemoryToken(
|
||||
result.value(),
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
return Token::CreateMemoryToken(result.value(), lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
return Token::CreateErrorToken(
|
||||
@@ -100,10 +89,7 @@ namespace Token
|
||||
}
|
||||
else if(memoryPrefix == '%')
|
||||
{
|
||||
return Token::CreateMemoryToken(
|
||||
GetRegisterType(valueString),
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
return Token::CreateMemoryToken(GetRegisterType(valueString), lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
return Token::CreateErrorToken(
|
||||
@@ -113,9 +99,7 @@ namespace Token
|
||||
lineColumn + 1u);
|
||||
}
|
||||
|
||||
Token GetUnterminatedCharacterLiteralError(
|
||||
std::size_t const lineNumber,
|
||||
std::size_t const lineColumn)
|
||||
Token GetUnterminatedCharacterLiteralError(std::size_t const lineNumber, std::size_t const lineColumn)
|
||||
{
|
||||
return Token::CreateErrorToken(
|
||||
"Unterminated character or string literal",
|
||||
@@ -138,10 +122,7 @@ namespace Token
|
||||
|
||||
if(result.has_value())
|
||||
{
|
||||
return Token::CreateImmediateValueToken(
|
||||
result.value(),
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
return Token::CreateImmediateValueToken(result.value(), lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
return Token::CreateErrorToken(
|
||||
@@ -152,8 +133,8 @@ namespace Token
|
||||
}
|
||||
|
||||
case '%':
|
||||
return Token::CreateRegisterToken(GetRegisterType(
|
||||
string.substr(1, string.size())),
|
||||
return Token::CreateRegisterToken(
|
||||
GetRegisterType(string.substr(1, string.size())),
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
|
||||
@@ -178,10 +159,7 @@ namespace Token
|
||||
|
||||
case ':':
|
||||
// TODO check if label is an Operand?
|
||||
return Token::CreateLabelDefinitionToken(
|
||||
string.substr(0, string.size() - 1),
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
return Token::CreateLabelDefinitionToken(string.substr(0, string.size() - 1), lineNumber, lineColumn);
|
||||
|
||||
case '\'':
|
||||
case '\"':
|
||||
@@ -199,10 +177,7 @@ namespace Token
|
||||
return Token::CreateLabelArgumentToken(string, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
void Tokenizer::Tokenize(
|
||||
std::string const & line,
|
||||
std::size_t const lineNumber,
|
||||
std::vector<Token> & tokens)
|
||||
void Tokenizer::Tokenize(std::string const & line, std::size_t const lineNumber, std::vector<Token> & tokens)
|
||||
{
|
||||
for(std::size_t column = 0u; column < line.size(); ++column)
|
||||
{
|
||||
@@ -216,10 +191,7 @@ namespace Token
|
||||
case '\'':
|
||||
case '\"':
|
||||
{
|
||||
auto const result = Utils::getValueSurroundedBy(
|
||||
line,
|
||||
column,
|
||||
line[column]);
|
||||
auto const result = Utils::getValueSurroundedBy(line, column, line[column]);
|
||||
if(result.has_value())
|
||||
{
|
||||
tokens.push_back(ExtractToken(result.value(), lineNumber, column));
|
||||
@@ -227,8 +199,7 @@ namespace Token
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens.push_back(
|
||||
GetUnterminatedCharacterLiteralError(lineNumber, column));
|
||||
tokens.push_back(GetUnterminatedCharacterLiteralError(lineNumber, column));
|
||||
|
||||
// Parsing must stop here, the line is malformed
|
||||
return;
|
||||
|
||||
@@ -2,15 +2,10 @@
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
bool isWhitespaceCharacter(char const c)
|
||||
{
|
||||
return c == '\n' || c == ' ' || c == '\t' || c == '\r';
|
||||
}
|
||||
bool isWhitespaceCharacter(char const c) { return c == '\n' || c == ' ' || c == '\t' || c == '\r'; }
|
||||
|
||||
std::optional<std::string> getValueSurroundedBy(
|
||||
std::string const & src,
|
||||
std::size_t const pos,
|
||||
char const surroundingCharacter)
|
||||
std::optional<std::string>
|
||||
getValueSurroundedBy(std::string const & src, std::size_t const pos, char const surroundingCharacter)
|
||||
{
|
||||
for(std::size_t i = pos + 1; i < src.size(); ++i)
|
||||
{
|
||||
@@ -23,9 +18,7 @@ namespace Utils
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string getValueSurroundedByWhitespace(
|
||||
std::string const & src,
|
||||
std::size_t const pos)
|
||||
std::string getValueSurroundedByWhitespace(std::string const & src, std::size_t const pos)
|
||||
{
|
||||
for(std::size_t i = pos + 1; i < src.size(); ++i)
|
||||
{
|
||||
@@ -40,10 +33,7 @@ namespace Utils
|
||||
|
||||
namespace Bytes
|
||||
{
|
||||
void Write(
|
||||
int const value,
|
||||
std::vector<std::uint8_t> & vec,
|
||||
std::size_t const pos)
|
||||
void Write(int const value, std::vector<std::uint8_t> & vec, std::size_t const pos)
|
||||
{
|
||||
vec[pos] = value & 0xFF;
|
||||
vec[pos + 1] = (value >> 8) & 0xFF;
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
|
||||
void PrintBadToken(Token::Token const & token, std::vector<std::string> const & lines)
|
||||
{
|
||||
std::printf("at line number %i, column %i: ",
|
||||
token.lineNumber + 1,
|
||||
token.lineColumn + 1);
|
||||
std::printf("at line number %i, column %i: ", token.lineNumber + 1, token.lineColumn + 1);
|
||||
std::puts(token.errorMessage.c_str());
|
||||
|
||||
std::printf("%s\n", lines[token.lineNumber].c_str());
|
||||
@@ -135,9 +133,7 @@ void Wassembler::ExecuteCode(std::vector<uint8_t> const & bytes)
|
||||
vm.Run();
|
||||
}
|
||||
|
||||
bool Wassembler::CompileFile(
|
||||
std::string const & filePath,
|
||||
std::vector<std::uint8_t> & bytes) const
|
||||
bool Wassembler::CompileFile(std::string const & filePath, std::vector<std::uint8_t> & bytes) const
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
if(!LoadTextFile(filePath, lines))
|
||||
@@ -162,25 +158,13 @@ bool Wassembler::CompileFile(
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wassembler::SetMemorySize(unsigned const size)
|
||||
{
|
||||
vm.SetMemorySize(size);
|
||||
}
|
||||
void Wassembler::SetMemorySize(unsigned const size) { vm.SetMemorySize(size); }
|
||||
|
||||
void Wassembler::EnableSubstitutionsLogging()
|
||||
{
|
||||
printSubstitutions = true;
|
||||
}
|
||||
void Wassembler::EnableSubstitutionsLogging() { printSubstitutions = true; }
|
||||
|
||||
void Wassembler::EnableTokensLogging()
|
||||
{
|
||||
printTokens = true;
|
||||
}
|
||||
void Wassembler::EnableTokensLogging() { printTokens = true; }
|
||||
|
||||
void Wassembler::EnableByteTranslationLogging()
|
||||
{
|
||||
printTranslatedBytes = true;
|
||||
}
|
||||
void Wassembler::EnableByteTranslationLogging() { printTranslatedBytes = true; }
|
||||
|
||||
bool Wassembler::CompileAndRun(std::string const & filePath)
|
||||
{
|
||||
@@ -204,8 +188,7 @@ bool Wassembler::CompileAndRun(std::string const & filePath)
|
||||
|
||||
bytes.resize(bytes.size() - (100 - inputFile.gcount()));
|
||||
}
|
||||
else if (filePath.size() > 5 &&
|
||||
filePath.compare(filePath.size() - 5, 5, ".wasm") == 0)
|
||||
else if(filePath.size() > 5 && filePath.compare(filePath.size() - 5, 5, ".wasm") == 0)
|
||||
{
|
||||
if(!CompileFile(filePath, bytes))
|
||||
{
|
||||
@@ -214,9 +197,7 @@ bool Wassembler::CompileAndRun(std::string const & filePath)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::printf(
|
||||
"Error: unrecognized file extension on input file %s",
|
||||
filePath.c_str());
|
||||
std::printf("Error: unrecognized file extension on input file %s", filePath.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -235,9 +216,7 @@ bool Wassembler::CompileAndRun(std::string const & filePath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wassembler::CompileToFile(
|
||||
std::string const & inputFilePath,
|
||||
std::string const & outputFilePath)
|
||||
bool Wassembler::CompileToFile(std::string const & inputFilePath, std::string const & outputFilePath)
|
||||
{
|
||||
std::vector<std::uint8_t> bytes;
|
||||
if(!CompileFile(inputFilePath, bytes))
|
||||
|
||||
Reference in New Issue
Block a user