This commit is contained in:
IlyaShurupov 2024-03-05 19:19:04 +03:00 committed by Ilya Shurupov
parent 1293136343
commit 8dc73bc1d5
11 changed files with 1179 additions and 308 deletions

View file

@ -9,7 +9,7 @@ Expression::Expression(Type type) :
ExpressionChild* Expression::ExprChild(tp::String id) { return new ExpressionChild(this, id); }
ExpressionCall* Expression::ExprCall(tp::InitialierList<Expression*> args) { return new ExpressionCall(this, args); }
ExpressionCall* Expression::ExprCall(ExpressionList* args) { return new ExpressionCall(this, args); }
ExpressionLocal* obj::BCgen::ExprLocal(tp::String id) { return new ExpressionLocal(id); }
@ -17,11 +17,15 @@ ExpressionSelf* obj::BCgen::ExprSelf() { return new ExpressionSelf(); }
ExpressionNew* obj::BCgen::ExprNew(tp::String type) { return new ExpressionNew(type); }
ExpressionAriphm* obj::BCgen::ExprAriphm(Expression* left, Expression* right, OpCode type) { return new ExpressionAriphm(left, right, type); }
ExpressionAriphm* obj::BCgen::ExprAriphm(Expression* left, Expression* right, OpCode type) {
return new ExpressionAriphm(left, right, type);
}
ExpressionFunc* obj::BCgen::ExprFunc(tp::String id) { return new ExpressionFunc(id); }
ExpressionBoolean* obj::BCgen::ExprBool(Expression* left, Expression* right, obj::OpCode type) { return new ExpressionBoolean(left, right, ExpressionBoolean::BoolType(type)); }
ExpressionBoolean* obj::BCgen::ExprBool(Expression* left, Expression* right, obj::OpCode type) {
return new ExpressionBoolean(left, right, ExpressionBoolean::BoolType(type));
}
ExpressionBoolean* obj::BCgen::ExprBoolNot(Expression* invert) { return new ExpressionBoolean(invert); }
@ -36,12 +40,15 @@ ExpressionBoolean::ExpressionBoolean(Expression* invert) :
mLeft(invert),
mBoolType(BoolType::NOT) {}
ExpressionCall::ExpressionCall(Expression* mParent, tp::InitialierList<Expression*> args) :
ExpressionCall::ExpressionCall(Expression* mParent, ExpressionList* args) :
Expression(Type::CALL),
mParent(mParent) {
mArgs = args;
}
ExpressionList::ExpressionList() :
Expression(Type::LIST) {}
ExpressionNew::ExpressionNew(tp::String type) :
Expression(Type::NEW),
mNewType(type) {}

View file

@ -348,8 +348,8 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
case Expression::Type::CALL:
{
auto call = (ExpressionCall*) expr;
inst(Instruction(OpCode::PUSH_ARGS, call->mArgs.size(), 1));
for (auto arg : call->mArgs) {
inst(Instruction(OpCode::PUSH_ARGS, call->mArgs->mItems.size(), 1));
for (auto arg : call->mArgs->mItems) {
EvalExpr(arg.data());
}
EvalExpr(call->mParent);

View file

@ -0,0 +1,186 @@
#include "Private.hpp"
#include <parser/parser.h>
using namespace obj::BCgen;
typedef lalr::ParserNode<SymbolType> Node;
static UserData scope(const UserData* start, const Node* nodes, size_t length) { return start[1]; }
static UserData stm_list_append(const UserData* start, const Node* nodes, size_t length) {
auto scope = (StatementScope*) start[0];
auto stm = (Statement*) start[2];
scope->mStatements.append(stm);
return scope;
}
static UserData stm_list_create(const UserData* start, const Node* nodes, size_t length) {
return new StatementScope({ (Statement*) start[0] }, true);
}
static UserData stm_log(const UserData* start, const Node* nodes, size_t length) {
auto expr = (Expression*) (start[1]);
return new StatementPrint(expr);
}
static UserData stm_assign(const UserData* start, const Node* nodes, size_t length) {
return new StatementCopy((Expression*) start[0], (Expression*) start[2]);
}
static UserData stm_var_def_new_type(const UserData* start, const Node* nodes, size_t length) {
return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), new ExpressionNew((char*) nodes[3].lexeme().c_str()));
}
static UserData stm_var_def_assign(const UserData* start, const Node* nodes, size_t length) {
return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), (Expression*) start[3]);
}
static UserData expr_function(const UserData* start, const Node* nodes, size_t length) {
auto expr = (Expression*) (start[0]);
auto args = (ExpressionList*) (start[2]);
return expr->ExprCall(args);
}
static UserData expr_method(const UserData* start, const Node* nodes, size_t length) {
auto expr = (Expression*) (start[0]);
auto args = (ExpressionList*) (start[4]);
auto childId = nodes[1].lexeme();
auto method = new ExpressionChild(expr, (char*) childId.c_str());
return method->ExprCall(args);
}
static UserData expr_list_append(const UserData* start, const Node* nodes, size_t length) {
auto list = (ExpressionList*) start[0];
auto expr = (Expression*) start[2];
list->mItems.append(expr);
return list;
}
static UserData expr_list_create(const UserData* start, const Node* nodes, size_t length) {
auto exprList = new ExpressionList();
exprList->mItems.append((Expression*) start[0]);
return exprList;
}
static UserData expr_child(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionChild((Expression*) start[0], (char*) nodes[2].lexeme().c_str());
}
static UserData expr_bool_eq(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL);
}
static UserData expr_bool_negate(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean((Expression*) start[1]);
}
static UserData expr_bool_neq(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::NOT_EQUAL);
}
static UserData expr_bool_grater(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::MORE);
}
static UserData expr_bool_lesser(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::LESS);
}
static UserData expr_bool_grater_eq(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean(
(Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_MORE
);
}
static UserData expr_bool_lesser_eq(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionBoolean(
(Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_LESS
);
}
static UserData expr_add(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_ADD);
}
static UserData expr_subtract(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_SUB);
}
static UserData expr_multiply(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_MUL);
}
static UserData expr_divide(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_DIV);
}
static UserData expr_compound(const UserData* start, const Node* nodes, size_t length) { return start[1]; }
static UserData expr_bool(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionConst(nodes[0].lexeme() == "true");
}
static UserData expr_int(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionConst(stoi(nodes[0].lexeme()));
}
static UserData expr_float(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionConst(stof(nodes[0].lexeme()));
}
static UserData expr_string(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionConst((char*) nodes[0].lexeme().c_str());
}
static UserData expr_id(const UserData* start, const Node* nodes, size_t length) {
return new ExpressionLocal((char*) nodes[0].lexeme().c_str());
}
static UserData tmp(const UserData* start, const Node* nodes, size_t length) {
// a
return *start;
}
#define BIND(name) parser.set_action_handler(#name, &(name));
void bind(LalrParser& parser) {
BIND(scope);
BIND(stm_list_append);
BIND(stm_list_create);
BIND(expr_list_append);
BIND(expr_list_create);
BIND(stm_var_def_new_type);
BIND(stm_var_def_assign);
BIND(stm_log);
BIND(stm_assign);
BIND(expr_function)
BIND(expr_method)
BIND(expr_child)
BIND(expr_bool_eq)
BIND(expr_bool_negate)
BIND(expr_bool_neq)
BIND(expr_bool_grater)
BIND(expr_bool_lesser)
BIND(expr_bool_grater_eq)
BIND(expr_bool_lesser_eq)
BIND(expr_add)
BIND(expr_subtract)
BIND(expr_multiply)
BIND(expr_divide)
BIND(expr_compound)
BIND(expr_bool)
BIND(expr_int)
BIND(expr_float)
BIND(expr_string)
BIND(expr_id)
BIND(tmp)
parser.set_lexer_action_handler("string", &lalr::string_literal<IteratorType>);
}

View file

@ -0,0 +1,16 @@
#pragma once
#include <lalr/Parser.hpp>
#include <lalr/string_literal.hpp>
typedef void* UserData;
typedef char SymbolType;
typedef std::basic_string<SymbolType>::iterator IteratorType;
extern const lalr::ParserStateMachine* oscript_parser_state_machine;
typedef lalr::Parser<IteratorType, UserData> LalrParser;
void bind(LalrParser& parser);

File diff suppressed because it is too large Load diff

View file

@ -1,33 +1,65 @@
oscript {
%whitespace "[ \t\r\n]*";
%whitespace "[ \t\r\n]*";
%none error;
%none integer;
%left '(' ')';
%left '+' '-';
%left '*' '/';
%left '.' '=';
%left '==' '>' '<' '>=' '<=' '!=' '!';
scope:
'{' statements '}' [scope]
| ;
scope:
'{' stmts '}' [scope]
| ;
statements:
statements ';' statement ';' [stm_scope_append]
| statement [stm_scope_create]
| ;
stmts:
stmts ';' stmt ';' [stm_list_append]
| stmt [stm_list_create]
| ;
statement:
statementVar [tmp]
| statementLog [tmp];
stmt:
stm_var_def_new_type [tmp]
| stm_var_def_assign [tmp]
| stm_log [tmp]
| stm_assign [tmp]
;
statementVar: 'var' id [stm_defVar];
statementLog: 'print' value [stm_log];
stm_var_def_new_type: 'var' id ':' id [stm_var_def_new_type];
stm_var_def_assign: 'var' id '=' expr [stm_var_def_assign];
stm_log: 'print' expr [stm_log];
stm_assign: expr '=' expr [stm_assign];
value:
boolean [expr_bool]
| integer [expr_int]
| real [expr_float]
| string [expr_string]
|
;
expr_list:
expr_list ',' expr ',' [expr_list_append]
| expr [expr_list_create]
| ;
id: "[a-z]";
boolean: "true|false";
integer: "(\+|\-)?[0-9]+";
real: "(\+|\-)?[0-9]+(\.[0-9]+)?((e|E)(\+|\-)?[0-9]+)?";
string: "[\"']:string:";
expr:
id '(' expr_list ')' [expr_function]
| expr '.' id '(' expr_list ')' [expr_method]
| expr '.' id [expr_child]
| expr '==' expr [expr_bool_eq]
| '!' expr [expr_bool_negate]
| expr '!=' expr [expr_bool_neq]
| expr '>' expr [expr_bool_grater]
| expr '<' expr [expr_bool_lesser]
| expr '>=' expr [expr_bool_grater_eq]
| expr '<=' expr [expr_bool_lesser_eq]
| expr '+' expr [expr_add]
| expr '-' expr [expr_subtract]
| expr '*' expr [expr_multiply]
| expr '/' expr [expr_divide]
| '(' expr ')' [expr_compound]
| boolean [expr_bool]
| integer [expr_int]
| real [expr_float]
| string [expr_string]
| id [expr_id]
;
id: "[a-z]";
boolean: "true|false";
integer: "(\+|\-)?[0-9]+";
real: "(\+|\-)?[0-9]+(\.[0-9]+)?((e|E)(\+|\-)?[0-9]+)?";
string: "[\"']:string:";
}

View file

@ -2,94 +2,18 @@
#include <parser/parser.h>
// #include "compiler/function.h"
#include <lalr/Parser.hpp>
#include <lalr/string_literal.hpp>
#include "Private.hpp"
using namespace obj;
struct ASTNode {
BCgen::Expression* expression = nullptr;
BCgen::Statement* statement = nullptr;
};
extern const lalr::ParserStateMachine* oscript_parser_state_machine;
typedef void* UserData;
typedef char SymbolType;
typedef std::basic_string<SymbolType>::iterator IteratorType;
namespace action {
static UserData expr_bool(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return new BCgen::ExpressionConst(nodes[0].lexeme() == "true");
}
static UserData expr_int(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return {};
}
static UserData expr_float(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return {};
}
static UserData expr_string(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return {};
}
static UserData stm_log(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
auto expr = (BCgen::Expression*) (start[1]);
return new BCgen::StatementPrint(expr);
}
static UserData stm_defVar(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return new BCgen::StatementLocalDef(nodes[1].lexeme().c_str(), new BCgen::ExpressionConst(false));
}
static UserData stm_scope_append(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
auto scope = (BCgen::StatementScope*) start[0];
auto stm = (BCgen::Statement*) start[2];
scope->mStatements.append(stm);
return scope;
}
static UserData stm_scope_create(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
auto stm = (BCgen::Statement*) start[0];
return new BCgen::StatementScope({ stm }, true);
}
static UserData scope(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return start[1];
}
static UserData tmp(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
return *start;
}
}
Parser::Result Parser::parse(const tp::String& stream) {
lalr::ErrorPolicy errorPolicy;
lalr::Parser<IteratorType, UserData> parser(oscript_parser_state_machine, &errorPolicy);
parser.set_lexer_action_handler("string", &lalr::string_literal<IteratorType>);
parser.set_action_handler("expr_bool", &action::expr_bool);
parser.set_action_handler("expr_int", &action::expr_int);
parser.set_action_handler("expr_float", &action::expr_float);
parser.set_action_handler("expr_string", &action::expr_string);
parser.set_action_handler("stm_defVar", &action::stm_defVar);
parser.set_action_handler("stm_log", &action::stm_log);
parser.set_action_handler("stm_scope_create", &action::stm_scope_create);
parser.set_action_handler("stm_scope_append", &action::stm_scope_append);
parser.set_action_handler("scope", &action::scope);
parser.set_action_handler("tmp", &action::tmp);
LalrParser parser(oscript_parser_state_machine, &errorPolicy);
bind(parser);
std::string streamStd(stream.read());
LALR_ASSERT(parser.valid());

View file

@ -24,6 +24,7 @@ namespace obj {
FUNC,
BOOLEAN,
SELF,
LIST,
} mType = Type::NONE;
bool mValueUsed = false;
@ -32,7 +33,12 @@ namespace obj {
Expression(Type type);
ExpressionChild* ExprChild(tp::String id);
ExpressionCall* ExprCall(tp::InitialierList<Expression*> args);
ExpressionCall* ExprCall(class ExpressionList* args);
};
struct ExpressionList : public Expression {
tp::Buffer<Expression*> mItems;
ExpressionList();
};
struct ExpressionNew : public Expression {
@ -59,8 +65,8 @@ namespace obj {
struct ExpressionCall : public Expression {
Expression* mParent = NULL;
tp::Buffer<Expression*> mArgs;
ExpressionCall(Expression* mParent, tp::InitialierList<Expression*> args);
ExpressionList* mArgs;
ExpressionCall(Expression* mParent, ExpressionList* args);
};
struct ExpressionAriphm : public Expression {

View file

@ -41,7 +41,10 @@ if (i == 10) {
)";
auto script = R"(
var i = 10;
{
var i = 10;
print (i + 10) * 5;
}
)";
TEST_DEF_STATIC(Complex) {
@ -64,7 +67,7 @@ TEST_DEF_STATIC(Simple) {
interpreter->getMember<LinkObject>("target method")->setLink(method);
method->mScript->mReadable->val = "<< 3;";
method->mScript->mReadable->val = script;
method->compile();
interpreter->exec();
@ -77,9 +80,12 @@ TEST_DEF_STATIC(Simple) {
NDO->destroy(interpreterLoaded);
NDO->destroy(interpreter);
printf("\n\nEnd\n\n");
}
TEST_DEF(Interpreter) {
testSimple();
exit(0);
// testComplex();
}

View file

@ -9,7 +9,7 @@ using namespace obj;
TEST_DEF_STATIC(Basic) {
Parser parser;
String stream = "{ var i; print false; }";
String stream = "{ var i = true; print (i + 1) * 10; }";
auto res = parser.parse(stream);
}

View file

@ -16,6 +16,11 @@ int main() {
tp::ModuleManifest* deps[] = { &gModuleObjects, nullptr };
tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps);
if (module.initialize()) {
testInterpreter();
module.deinitialize();
}
if (module.initialize()) {
testParser();
module.deinitialize();
@ -31,10 +36,5 @@ int main() {
module.deinitialize();
}
if (module.initialize()) {
testInterpreter();
module.deinitialize();
}
return 0;
}