Compare commits

..

No commits in common. "main" and "v0.1" have entirely different histories.
main ... v0.1

10 changed files with 51 additions and 42 deletions

6
.gitignore vendored
View file

@ -1,5 +1 @@
[Bb]uild/ build
[Oo]ut/
.vs/
*.json

View file

@ -1,12 +0,0 @@
# The Bisquit Programming Language
Bisquit is a first attempt at designing and implementing a simple, interpreted language; Drawing inspiration from typical assembly languages and BASIC.
For a quick tour of the language, check the PDF in the /doc/ directory, and check out the the supplied example programs.
To build the interpreter, go to the root of the project directory and do:
mkdir build && cd build
cmake ..
make
The bisquit_interpreter executable will then be built.

View file

@ -1,5 +1,5 @@
PRINT "Hello World, this is a number: " 15 PRINT "Hello World, this is a number: " 15
ASSIGN 15 number ASSIGN number 15
PRINT "Let's double it's value, shall we?" PRINT "Let's double it's value, shall we?"
ADD number number number ADD number number number
PRINT "There we go: " number PRINT "There we go: " number

View file

@ -3,7 +3,7 @@
#include <string> #include <string>
enum class TokenType enum TokenType
{ {
KEYWORD, KEYWORD,
IDENTIFIER, IDENTIFIER,
@ -11,7 +11,7 @@ enum class TokenType
ID_OR_LIT ID_OR_LIT
}; };
enum class ValueType enum ValueType
{ {
STRING, STRING,
NUMBER, NUMBER,
@ -20,12 +20,12 @@ enum class ValueType
// some prototypes // some prototypes
struct Token; struct Token;
struct Instruction; class Instruction;
struct Keyword; struct Keyword;
struct Runtime; class Runtime;
std::string resolve_TokenType_str(TokenType); const std::string resolve_TokenType_str(enum TokenType);
std::string resolve_ValueType_str(ValueType); const std::string resolve_ValueType_str(enum ValueType);
#endif //BISCUIT_INTERPRETER_COMMON_HPP #endif //BISCUIT_INTERPRETER_COMMON_HPP

View file

@ -29,9 +29,9 @@ struct WrongArgumentCountExcept : public std::exception
struct WrongTokenExcept : public std::exception struct WrongTokenExcept : public std::exception
{ {
TokenType expected, got; enum TokenType expected, got;
std::string keyword_name, token_str; std::string keyword_name, token_str;
inline WrongTokenExcept(const std::string& _keyword_name, const std::string& _token_str, TokenType _expected, TokenType _got) inline WrongTokenExcept(const std::string& _keyword_name, const std::string& _token_str, const enum TokenType& _expected, const enum TokenType& _got)
: expected(_expected), got(_got), keyword_name(_keyword_name), token_str(_token_str) {} : expected(_expected), got(_got), keyword_name(_keyword_name), token_str(_token_str) {}
}; };
@ -39,9 +39,9 @@ struct WrongTokenExcept : public std::exception
// Runtime errors // Runtime errors
struct TypeErrorExcept : public std::exception struct TypeErrorExcept : public std::exception
{ {
ValueType expected, got; enum ValueType expected, got;
std::string token_str; std::string token_str;
inline TypeErrorExcept(const std::string& _token_str, ValueType _expected, ValueType _got) inline TypeErrorExcept(const std::string& _token_str, const enum ValueType& _expected, const enum ValueType& _got)
: expected(_expected), got(_got), token_str(_token_str) {} : expected(_expected), got(_got), token_str(_token_str) {}
}; };

View file

@ -169,9 +169,9 @@ const std::vector<Keyword> keywords =
float condition; float condition;
if(tokens[0].type == TokenType::LITERAL) if(tokens[0].type == TokenType::LITERAL)
dest = static_cast<int>(std::floor(tokens[0].val_number)); dest = std::floor(tokens[0].val_number);
else else
dest = static_cast<int>(std::floor(rt.resolve_var_num(tokens[0].val_string))); dest = std::floor(rt.resolve_var_num(tokens[0].val_string));
if(tokens[1].type == TokenType::LITERAL) if(tokens[1].type == TokenType::LITERAL)
condition = std::floor(tokens[1].val_number); condition = std::floor(tokens[1].val_number);
@ -193,16 +193,16 @@ const std::vector<Keyword> keywords =
float condition; float condition;
if(tokens[0].type == TokenType::LITERAL) if(tokens[0].type == TokenType::LITERAL)
offset = static_cast<int>(std::floor(tokens[0].val_number)); offset = std::floor(tokens[0].val_number);
else else
offset = static_cast<int>(std::floor(rt.resolve_var_num(tokens[0].val_string))); offset = std::floor(rt.resolve_var_num(tokens[0].val_string));
if(tokens[1].type == TokenType::LITERAL) if(tokens[1].type == TokenType::LITERAL)
condition = std::floor(tokens[1].val_number); condition = std::floor(tokens[1].val_number);
else else
condition = std::floor(rt.resolve_var_num(tokens[1].val_string)); condition = std::floor(rt.resolve_var_num(tokens[1].val_string));
dest = rt.instruction_counter + offset; dest = rt.instruction_counter + dest;
if(condition > 0.0f) if(condition > 0.0f)
rt.jump_instructions(dest); rt.jump_instructions(dest);
@ -253,13 +253,13 @@ const std::vector<Keyword> keywords =
{ {
int limit; int limit;
if(tokens[0].type == TokenType::LITERAL) if(tokens[0].type == TokenType::LITERAL)
limit = static_cast<int>(tokens[0].val_number); limit = tokens[0].val_number;
else else
limit = static_cast<int>(rt.resolve_var_num(tokens[0].val_string)); limit = rt.resolve_var_num(tokens[0].val_string);
int number = rand() % limit; int number = rand() % limit;
rt.assign_var_num(tokens[1].val_string, static_cast<float>(number)); rt.assign_var_num(tokens[1].val_string, number);
} }
}, },
{ {

View file

@ -1,3 +1,7 @@
#if defined(WIN32) || defined(WIN32) || defined(__WIN32)
#include <Windows.h>
#endif
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <fstream> #include <fstream>
@ -9,6 +13,21 @@
#include "parse.hpp" #include "parse.hpp"
#include "runtime.hpp" #include "runtime.hpp"
bool request_console();
// Must request console on Windows
#if defined(WIN32) || defined(WIN32) || defined(__WIN32)
bool request_console()
{
return AllocConsole();
}
#else
bool request_console()
{
return true;
}
#endif
std::ifstream get_infile(int argc, char ** argv) std::ifstream get_infile(int argc, char ** argv)
{ {
if(argc != 2) if(argc != 2)
@ -35,6 +54,13 @@ int main(int argc, char * argv[])
std::stringstream buffer; std::stringstream buffer;
buffer << infile.rdbuf(); buffer << infile.rdbuf();
// On Windows, we have to explicitly request a console
/*if(!request_console())
{
std::cerr << "Failed to get console!" << std::endl;
exit(EXIT_FAILURE);
}*/
std::vector<Instruction> instructions = parse_instructions(buffer.str()); std::vector<Instruction> instructions = parse_instructions(buffer.str());
Runtime rt(instructions); Runtime rt(instructions);

View file

@ -50,7 +50,7 @@ std::vector<Token> tokenize_line(const std::string& line)
} }
} }
return tokens; return std::move(tokens);
} }
// Main parsing function // Main parsing function
@ -115,7 +115,7 @@ std::vector<Instruction> parse_instructions(const std::string& code_arg)
} }
return instructions; return std::move(instructions);
} }
bool is_keyword(std::string str) bool is_keyword(std::string str)
@ -279,7 +279,7 @@ Instruction::Instruction(std::vector<Token>& _token_list)
// Make sure the keyword gets the number of arguments it needs // Make sure the keyword gets the number of arguments it needs
if(keyword_ptr->expected_num_args != -1 && (keyword_ptr->expected_num_args != tokens.size() - 1)) if(keyword_ptr->expected_num_args != -1 && (keyword_ptr->expected_num_args != tokens.size() - 1))
throw WrongArgumentCountExcept(keyword_ptr->name, keyword_ptr->expected_num_args, static_cast<int>(tokens.size() - 1)); throw WrongArgumentCountExcept(keyword_ptr->name, keyword_ptr->expected_num_args, tokens.size() - 1);
// Check the arguments supplied are the right kind of tokens // Check the arguments supplied are the right kind of tokens
for(int i = 0; i < keyword_ptr->expected_num_args; i++) for(int i = 0; i < keyword_ptr->expected_num_args; i++)

View file

@ -1,6 +1,5 @@
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#include <algorithm>
#include "runtime.hpp" #include "runtime.hpp"
#include "exceptions.hpp" #include "exceptions.hpp"

View file

@ -1,7 +1,7 @@
#include "common.hpp" #include "common.hpp"
#include <string> #include <string>
std::string resolve_TokenType_str(TokenType ttype) const std::string resolve_TokenType_str(enum TokenType ttype)
{ {
switch(ttype) switch(ttype)
{ {
@ -22,7 +22,7 @@ std::string resolve_TokenType_str(TokenType ttype)
return "UNKNOW TOKENTYPE"; return "UNKNOW TOKENTYPE";
} }
std::string resolve_ValueType_str(ValueType vtype) const std::string resolve_ValueType_str(enum ValueType vtype)
{ {
switch(vtype) switch(vtype)
{ {