Compare commits
15 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bc409bc989 | ||
![]() |
39fdbdf798 | ||
![]() |
ac3671def5 | ||
![]() |
f348d4fc08 | ||
![]() |
2ab8c2eaee | ||
![]() |
f1f0be77ae | ||
![]() |
d63dbea5fb | ||
![]() |
44a7ea539d | ||
![]() |
5d6ed9d504 | ||
![]() |
f9dc28173e | ||
![]() |
b930b3e380 | ||
![]() |
3eaf121c2c | ||
![]() |
fb2183957c | ||
![]() |
f7015bc23d | ||
![]() |
37d31e242c |
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1 +1,5 @@
|
||||||
build
|
[Bb]uild/
|
||||||
|
[Oo]ut/
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
*.json
|
||||||
|
|
12
README.md
Normal file
12
README.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# 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.
|
|
@ -1,5 +1,5 @@
|
||||||
PRINT "Hello World, this is a number: " 15
|
PRINT "Hello World, this is a number: " 15
|
||||||
ASSIGN number 15
|
ASSIGN 15 number
|
||||||
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
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum TokenType
|
enum class TokenType
|
||||||
{
|
{
|
||||||
KEYWORD,
|
KEYWORD,
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
|
@ -11,7 +11,7 @@ enum TokenType
|
||||||
ID_OR_LIT
|
ID_OR_LIT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ValueType
|
enum class ValueType
|
||||||
{
|
{
|
||||||
STRING,
|
STRING,
|
||||||
NUMBER,
|
NUMBER,
|
||||||
|
@ -20,12 +20,12 @@ enum ValueType
|
||||||
|
|
||||||
// some prototypes
|
// some prototypes
|
||||||
struct Token;
|
struct Token;
|
||||||
class Instruction;
|
struct Instruction;
|
||||||
struct Keyword;
|
struct Keyword;
|
||||||
class Runtime;
|
struct Runtime;
|
||||||
|
|
||||||
const std::string resolve_TokenType_str(enum TokenType);
|
std::string resolve_TokenType_str(TokenType);
|
||||||
const std::string resolve_ValueType_str(enum ValueType);
|
std::string resolve_ValueType_str(ValueType);
|
||||||
|
|
||||||
|
|
||||||
#endif //BISCUIT_INTERPRETER_COMMON_HPP
|
#endif //BISCUIT_INTERPRETER_COMMON_HPP
|
||||||
|
|
|
@ -29,9 +29,9 @@ struct WrongArgumentCountExcept : public std::exception
|
||||||
|
|
||||||
struct WrongTokenExcept : public std::exception
|
struct WrongTokenExcept : public std::exception
|
||||||
{
|
{
|
||||||
enum TokenType expected, got;
|
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, const enum TokenType& _expected, const enum TokenType& _got)
|
inline WrongTokenExcept(const std::string& _keyword_name, const std::string& _token_str, TokenType _expected, 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
|
||||||
{
|
{
|
||||||
enum ValueType expected, got;
|
ValueType expected, got;
|
||||||
std::string token_str;
|
std::string token_str;
|
||||||
inline TypeErrorExcept(const std::string& _token_str, const enum ValueType& _expected, const enum ValueType& _got)
|
inline TypeErrorExcept(const std::string& _token_str, ValueType _expected, ValueType _got)
|
||||||
: expected(_expected), got(_got), token_str(_token_str) {}
|
: expected(_expected), got(_got), token_str(_token_str) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 = std::floor(tokens[0].val_number);
|
dest = static_cast<int>(std::floor(tokens[0].val_number));
|
||||||
else
|
else
|
||||||
dest = std::floor(rt.resolve_var_num(tokens[0].val_string));
|
dest = static_cast<int>(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 = std::floor(tokens[0].val_number);
|
offset = static_cast<int>(std::floor(tokens[0].val_number));
|
||||||
else
|
else
|
||||||
offset = std::floor(rt.resolve_var_num(tokens[0].val_string));
|
offset = static_cast<int>(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 + dest;
|
dest = rt.instruction_counter + offset;
|
||||||
|
|
||||||
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 = tokens[0].val_number;
|
limit = static_cast<int>(tokens[0].val_number);
|
||||||
else
|
else
|
||||||
limit = rt.resolve_var_num(tokens[0].val_string);
|
limit = static_cast<int>(rt.resolve_var_num(tokens[0].val_string));
|
||||||
|
|
||||||
int number = rand() % limit;
|
int number = rand() % limit;
|
||||||
|
|
||||||
rt.assign_var_num(tokens[1].val_string, number);
|
rt.assign_var_num(tokens[1].val_string, static_cast<float>(number));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
26
src/main.cpp
26
src/main.cpp
|
@ -1,7 +1,3 @@
|
||||||
#if defined(WIN32) || defined(WIN32) || defined(__WIN32)
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -13,21 +9,6 @@
|
||||||
#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)
|
||||||
|
@ -54,13 +35,6 @@ 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);
|
||||||
|
|
|
@ -50,7 +50,7 @@ std::vector<Token> tokenize_line(const std::string& line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(tokens);
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main parsing function
|
// Main parsing function
|
||||||
|
@ -115,7 +115,7 @@ std::vector<Instruction> parse_instructions(const std::string& code_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return std::move(instructions);
|
return 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, tokens.size() - 1);
|
throw WrongArgumentCountExcept(keyword_ptr->name, keyword_ptr->expected_num_args, static_cast<int>(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++)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "runtime.hpp"
|
#include "runtime.hpp"
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const std::string resolve_TokenType_str(enum TokenType ttype)
|
std::string resolve_TokenType_str(TokenType ttype)
|
||||||
{
|
{
|
||||||
switch(ttype)
|
switch(ttype)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ const std::string resolve_TokenType_str(enum TokenType ttype)
|
||||||
return "UNKNOW TOKENTYPE";
|
return "UNKNOW TOKENTYPE";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string resolve_ValueType_str(enum ValueType vtype)
|
std::string resolve_ValueType_str(ValueType vtype)
|
||||||
{
|
{
|
||||||
switch(vtype)
|
switch(vtype)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue