mirror of
https://github.com/autc04/Retro68.git
synced 2025-01-14 08:33:16 +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 <cassert>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
int Expression::evaluateInt(ResourceCompiler *ctx)
|
||||
{
|
||||
@ -78,6 +79,21 @@ int BinaryExpr::evaluateInt(ResourceCompiler *ctx)
|
||||
return a->evaluateInt(ctx) * b->evaluateInt(ctx);
|
||||
case BinaryOp::DIVIDE:
|
||||
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)
|
||||
: id(id), isFunction(isFunction)
|
||||
IdentifierExpr::IdentifierExpr(std::string id)
|
||||
: id(id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,33 +136,11 @@ ExprPtr IdentifierExpr::lookup(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);
|
||||
}
|
||||
}
|
||||
|
||||
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
|
||||
{
|
||||
assert(!isFunction);
|
||||
return lookup(ctx)->evaluateString(ctx);
|
||||
}
|
||||
|
||||
@ -155,3 +149,40 @@ CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr 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
|
||||
{
|
||||
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
|
||||
@ -87,6 +87,7 @@ public:
|
||||
~BinaryExpr();
|
||||
|
||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||
};
|
||||
|
||||
class UnaryExpr : public Expression
|
||||
@ -103,11 +104,10 @@ public:
|
||||
|
||||
class IdentifierExpr : public Expression
|
||||
{
|
||||
public:
|
||||
std::string id;
|
||||
std::vector<ExprPtr> arguments;
|
||||
bool isFunction;
|
||||
public:
|
||||
IdentifierExpr(std::string id, bool isFunction = false);
|
||||
IdentifierExpr(std::string id);
|
||||
|
||||
void addArgument(ExprPtr e);
|
||||
ExprPtr lookup(ResourceCompiler *ctx);
|
||||
@ -115,4 +115,38 @@ public:
|
||||
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
|
||||
|
@ -198,7 +198,15 @@ RezSymbol RezLexer::nextToken()
|
||||
KEYWORD(BITSTRING, "bitstring"),
|
||||
|
||||
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();
|
||||
|
@ -71,6 +71,14 @@
|
||||
%token RECT "rect";
|
||||
%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 "^";
|
||||
@ -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; }
|
||||
| "{" resource_body "}" { $$ = $2; }
|
||||
| string { $$ = std::make_shared<StringExpr>($1); }
|
||||
| string_expression { $$ = $1; }
|
||||
;
|
||||
|
||||
expression : expression1 { $$ = $1; }
|
||||
@ -362,17 +363,29 @@ expression7 : expression8 { $$ = $1; }
|
||||
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||
|
||||
| IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($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(); }
|
||||
| identifier_expression { $$ = $1; }
|
||||
| "(" 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 ;
|
||||
@ -382,6 +395,22 @@ function_argument_list1 : 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 "}"
|
||||
{
|
||||
int id = $expression->evaluateInt(nullptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user