mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-29 10:55:00 +00:00
string concat, $$read function; make function names keywords
This commit is contained in:
parent
df0e042120
commit
3aed54a672
@ -2,6 +2,7 @@
|
|||||||
#include "ResourceCompiler.h"
|
#include "ResourceCompiler.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
int Expression::evaluateInt(ResourceCompiler *ctx)
|
int Expression::evaluateInt(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
@ -78,6 +79,21 @@ int BinaryExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
return a->evaluateInt(ctx) * b->evaluateInt(ctx);
|
return a->evaluateInt(ctx) * b->evaluateInt(ctx);
|
||||||
case BinaryOp::DIVIDE:
|
case BinaryOp::DIVIDE:
|
||||||
return a->evaluateInt(ctx) / b->evaluateInt(ctx);
|
return a->evaluateInt(ctx) / b->evaluateInt(ctx);
|
||||||
|
default:
|
||||||
|
throw TypeError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BinaryExpr::evaluateString(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
switch(op)
|
||||||
|
{
|
||||||
|
case BinaryOp::CONCAT:
|
||||||
|
return a->evaluateString(ctx) + b->evaluateString(ctx);
|
||||||
|
default:
|
||||||
|
throw TypeError();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +114,8 @@ int UnaryExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdentifierExpr::IdentifierExpr(std::string id, bool isFunction)
|
IdentifierExpr::IdentifierExpr(std::string id)
|
||||||
: id(id), isFunction(isFunction)
|
: id(id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,34 +135,12 @@ ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
|
int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
|
||||||
{
|
|
||||||
if(isFunction)
|
|
||||||
{
|
|
||||||
if(id == "$$countof" || id == "$$arrayindex")
|
|
||||||
{
|
|
||||||
assert(arguments.size() == 1);
|
|
||||||
IdentifierExprPtr arr = std::dynamic_pointer_cast<IdentifierExpr>(arguments[0]);
|
|
||||||
assert(arr);
|
|
||||||
if(id == "$$countof")
|
|
||||||
return ctx->getArrayCount(arr->id);
|
|
||||||
else
|
|
||||||
return ctx->getArrayIndex(arr->id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << id << std::endl;
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return lookup(ctx)->evaluateInt(ctx);
|
return lookup(ctx)->evaluateInt(ctx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
|
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
assert(!isFunction);
|
|
||||||
return lookup(ctx)->evaluateString(ctx);
|
return lookup(ctx)->evaluateString(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,3 +149,40 @@ CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr)
|
|||||||
: tag(tag), expr(expr)
|
: tag(tag), expr(expr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CountOfExpr::evaluateInt(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
assert(arg->arguments.size() == 0);
|
||||||
|
return ctx->getArrayCount(arg->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ArrayIndexExpr::evaluateInt(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
assert(arg->arguments.size() == 0);
|
||||||
|
return ctx->getArrayIndex(arg->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string ReadExpr::evaluateString(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
std::string filename = arg->evaluateString(ctx);
|
||||||
|
std::ifstream instream(filename);
|
||||||
|
// ### TODO: check error
|
||||||
|
return std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
|
||||||
|
std::istreambuf_iterator<char>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int UnimplementedExpr::evaluateInt(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
std::cerr << msg << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx)
|
||||||
|
{
|
||||||
|
std::cerr << msg << std::endl;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@ typedef std::shared_ptr<CaseExpr> CaseExprPtr;
|
|||||||
|
|
||||||
enum class BinaryOp
|
enum class BinaryOp
|
||||||
{
|
{
|
||||||
XOR, OR, AND, SHIFTLEFT, SHIFTRIGHT, EQUAL, NOTEQUAL, PLUS, MINUS, MULTIPLY, DIVIDE
|
XOR, OR, AND, SHIFTLEFT, SHIFTRIGHT, EQUAL, NOTEQUAL, PLUS, MINUS, MULTIPLY, DIVIDE, CONCAT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class UnaryOp
|
enum class UnaryOp
|
||||||
@ -87,6 +87,7 @@ public:
|
|||||||
~BinaryExpr();
|
~BinaryExpr();
|
||||||
|
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnaryExpr : public Expression
|
class UnaryExpr : public Expression
|
||||||
@ -103,11 +104,10 @@ public:
|
|||||||
|
|
||||||
class IdentifierExpr : public Expression
|
class IdentifierExpr : public Expression
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
std::string id;
|
std::string id;
|
||||||
std::vector<ExprPtr> arguments;
|
std::vector<ExprPtr> arguments;
|
||||||
bool isFunction;
|
IdentifierExpr(std::string id);
|
||||||
public:
|
|
||||||
IdentifierExpr(std::string id, bool isFunction = false);
|
|
||||||
|
|
||||||
void addArgument(ExprPtr e);
|
void addArgument(ExprPtr e);
|
||||||
ExprPtr lookup(ResourceCompiler *ctx);
|
ExprPtr lookup(ResourceCompiler *ctx);
|
||||||
@ -115,4 +115,38 @@ public:
|
|||||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CountOfExpr : public Expression
|
||||||
|
{
|
||||||
|
IdentifierExprPtr arg;
|
||||||
|
public:
|
||||||
|
CountOfExpr(IdentifierExprPtr arg) : arg(arg) {}
|
||||||
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ArrayIndexExpr : public Expression
|
||||||
|
{
|
||||||
|
IdentifierExprPtr arg;
|
||||||
|
public:
|
||||||
|
ArrayIndexExpr(IdentifierExprPtr arg) : arg(arg) {}
|
||||||
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReadExpr : public Expression
|
||||||
|
{
|
||||||
|
ExprPtr arg;
|
||||||
|
public:
|
||||||
|
ReadExpr(ExprPtr arg) : arg(arg) {}
|
||||||
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnimplementedExpr : public Expression
|
||||||
|
{
|
||||||
|
std::string msg;
|
||||||
|
public:
|
||||||
|
UnimplementedExpr(std::string msg) : msg(msg) {}
|
||||||
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // EXPRESSION_H
|
#endif // EXPRESSION_H
|
||||||
|
@ -198,7 +198,15 @@ RezSymbol RezLexer::nextToken()
|
|||||||
KEYWORD(BITSTRING, "bitstring"),
|
KEYWORD(BITSTRING, "bitstring"),
|
||||||
|
|
||||||
KEYWORD(INTEGER, "int"),
|
KEYWORD(INTEGER, "int"),
|
||||||
KEYWORD(DOLLAR, "$")
|
KEYWORD(DOLLAR, "$"),
|
||||||
|
|
||||||
|
KEYWORD(FUN_COUNTOF, "$$countof"),
|
||||||
|
KEYWORD(FUN_ARRAYINDEX, "$$arrayindex"),
|
||||||
|
KEYWORD(FUN_READ, "$$read"),
|
||||||
|
KEYWORD(FUN_BITFIELD, "$$bitfield"),
|
||||||
|
KEYWORD(FUN_WORD, "$$word"),
|
||||||
|
KEYWORD(FUN_BYTE, "$$byte"),
|
||||||
|
KEYWORD(FUN_LONG, "$$long"),
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string s = tok.get_value().c_str();
|
std::string s = tok.get_value().c_str();
|
||||||
|
@ -71,6 +71,14 @@
|
|||||||
%token RECT "rect";
|
%token RECT "rect";
|
||||||
%token BITSTRING "bitstring";
|
%token BITSTRING "bitstring";
|
||||||
|
|
||||||
|
%token FUN_COUNTOF "$$countof";
|
||||||
|
%token FUN_ARRAYINDEX "$$arrayindex";
|
||||||
|
%token FUN_READ "$$read";
|
||||||
|
%token FUN_BITFIELD "$$bitfield";
|
||||||
|
%token FUN_WORD "$$word";
|
||||||
|
%token FUN_BYTE "$$byte";
|
||||||
|
%token FUN_LONG "$$long";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
%left "|";
|
%left "|";
|
||||||
%left "^";
|
%left "^";
|
||||||
@ -309,17 +317,10 @@ switch_case : "case" IDENTIFIER ":"
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <std::string> string onestring;
|
|
||||||
string : onestring { $$ = $1; }
|
|
||||||
| string onestring { $$ = $1 + $2; }
|
|
||||||
;
|
|
||||||
onestring : STRINGLIT { $$ = $1; }
|
|
||||||
| DOLLAR STRINGLIT { $$ = fromHex($2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
value : expression { $$ = $1; }
|
value : expression { $$ = $1; }
|
||||||
| "{" resource_body "}" { $$ = $2; }
|
| "{" resource_body "}" { $$ = $2; }
|
||||||
| string { $$ = std::make_shared<StringExpr>($1); }
|
| string_expression { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression : expression1 { $$ = $1; }
|
expression : expression1 { $$ = $1; }
|
||||||
@ -362,17 +363,29 @@ expression7 : expression8 { $$ = $1; }
|
|||||||
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||||
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
|
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||||
|
|
||||||
| IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1); }
|
| identifier_expression { $$ = $1; }
|
||||||
| IDENTIFIER
|
|
||||||
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1,true)); }
|
|
||||||
"(" function_argument_list ")"
|
|
||||||
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
|
|
||||||
| IDENTIFIER
|
|
||||||
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1,false)); }
|
|
||||||
"[" function_argument_list1 "]"
|
|
||||||
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
|
|
||||||
| "(" expression ")" { $$ = $2; }
|
| "(" expression ")" { $$ = $2; }
|
||||||
|
|
||||||
|
| "$$countof" "(" identifier_expression ")"
|
||||||
|
{ $$ = std::make_shared<CountOfExpr>($identifier_expression); }
|
||||||
|
| "$$arrayindex" "(" identifier_expression ")"
|
||||||
|
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
|
||||||
|
| "$$bitfield" "(" expression "," expression "," expression ")"
|
||||||
|
{ $$ = std::make_shared<UnimplementedExpr>("$$bitfield"); }
|
||||||
|
| "$$word" "(" expression ")"
|
||||||
|
{ $$ = std::make_shared<UnimplementedExpr>("$$word"); }
|
||||||
|
| "$$byte" "(" expression ")"
|
||||||
|
{ $$ = std::make_shared<UnimplementedExpr>("$$byte"); }
|
||||||
|
| "$$long" "(" expression ")"
|
||||||
|
{ $$ = std::make_shared<UnimplementedExpr>("$$long"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <IdentifierExprPtr> identifier_expression;
|
||||||
|
identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1); }
|
||||||
|
| IDENTIFIER
|
||||||
|
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1)); }
|
||||||
|
"[" function_argument_list1 "]"
|
||||||
|
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
function_argument_list : %empty | function_argument_list1 ;
|
function_argument_list : %empty | function_argument_list1 ;
|
||||||
@ -382,6 +395,22 @@ function_argument_list1 : expression
|
|||||||
{ world.functionCalls.top()->addArgument($expression); }
|
{ world.functionCalls.top()->addArgument($expression); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
%type <ExprPtr> string_expression string_expression1;
|
||||||
|
string_expression : string_expression1 { $$ = $1; }
|
||||||
|
| string_expression string_expression1
|
||||||
|
{ $$ = std::make_shared<BinaryExpr>(BinaryOp::CONCAT, $1, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <std::string> stringlit;
|
||||||
|
stringlit : STRINGLIT { $$ = $1; }
|
||||||
|
| DOLLAR STRINGLIT { $$ = fromHex($2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1); }
|
||||||
|
| "$$read" "(" string_expression ")"
|
||||||
|
{ $$ = std::make_shared<ReadExpr>($string_expression); }
|
||||||
|
;
|
||||||
|
|
||||||
resource : "resource" res_type "(" expression resource_attributes ")" "{" resource_body "}"
|
resource : "resource" res_type "(" expression resource_attributes ")" "{" resource_body "}"
|
||||||
{
|
{
|
||||||
int id = $expression->evaluateInt(nullptr);
|
int id = $expression->evaluateInt(nullptr);
|
||||||
|
Loading…
Reference in New Issue
Block a user