mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-13 18:34:45 +00:00
start with semantics
This commit is contained in:
parent
cb554ed40f
commit
2b3e533937
@ -43,6 +43,9 @@ add_executable(Rez
|
||||
RezLexer.cc
|
||||
RezLexerWaveToken.h
|
||||
RezLexerNextToken.cc
|
||||
|
||||
ResourceDefinitions.cc
|
||||
ResourceDefinitions.h
|
||||
)
|
||||
target_link_libraries(Rez ${Boost_LIBRARIES})
|
||||
|
||||
|
27
Rez/ResourceDefinitions.cc
Normal file
27
Rez/ResourceDefinitions.cc
Normal file
@ -0,0 +1,27 @@
|
||||
#include "ResourceDefinitions.h"
|
||||
#include <ostream>
|
||||
|
||||
ResourceDefinitions::ResourceDefinitions()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, ResType t)
|
||||
{
|
||||
char c1 = static_cast<char>((int)t >> 24);
|
||||
char c2 = static_cast<char>((int)t >> 16);
|
||||
char c3 = static_cast<char>((int)t >> 8);
|
||||
char c4 = static_cast<char>((int)t);
|
||||
|
||||
out << "'" << c1 << c2 << c3 << c4 << "'";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, TypeSpec ts)
|
||||
{
|
||||
out << ts.getType();
|
||||
if(ts.hasID())
|
||||
out << " (" << ts.getID() << ")";
|
||||
return out;
|
||||
}
|
112
Rez/ResourceDefinitions.h
Normal file
112
Rez/ResourceDefinitions.h
Normal file
@ -0,0 +1,112 @@
|
||||
#ifndef RESOURCEDEFINITIONS_H
|
||||
#define RESOURCEDEFINITIONS_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
class ResType
|
||||
{
|
||||
int x;
|
||||
public:
|
||||
ResType() : x(0) {}
|
||||
ResType(int x) : x(x) {}
|
||||
operator int() const { return x; }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, ResType t);
|
||||
|
||||
class TypeSpec
|
||||
{
|
||||
ResType type;
|
||||
int id;
|
||||
public:
|
||||
static const int noID = 65536;
|
||||
|
||||
TypeSpec() : id(noID) {}
|
||||
TypeSpec(ResType type) : type(type), id(noID) {}
|
||||
TypeSpec(ResType type, int id) : type(type), id(id) {}
|
||||
|
||||
ResType getType() const { return type; }
|
||||
int getID() const { return id; }
|
||||
|
||||
bool hasID() const { return id != noID; }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, TypeSpec ts);
|
||||
|
||||
class Context
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
//virtual int evaluateInt(Context *ctx);
|
||||
|
||||
};
|
||||
|
||||
class StringExpr : public Expression
|
||||
{
|
||||
std::string str;
|
||||
public:
|
||||
StringExpr(const std::string& str) : str(str) {}
|
||||
};
|
||||
|
||||
class IntExpr : public Expression
|
||||
{
|
||||
int val;
|
||||
public:
|
||||
IntExpr(int val) : val(val) {}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Expression> ExprPtr;
|
||||
|
||||
class Field
|
||||
{
|
||||
public:
|
||||
virtual bool needsValue() { return true; }
|
||||
};
|
||||
typedef std::shared_ptr<Field> FieldPtr;
|
||||
|
||||
class SimpleField : public Field
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
boolean, byte, integer, longint, rect, point, char_,
|
||||
pstring, wstring, string, bitstring
|
||||
};
|
||||
|
||||
enum class Attrs
|
||||
{
|
||||
none = 0, hex = 1, key = 2, unsigned_ = 4, literal = 8
|
||||
};
|
||||
|
||||
Type type;
|
||||
Attrs attrs = Attrs::none;
|
||||
ExprPtr arrayCount;
|
||||
|
||||
ExprPtr value;
|
||||
std::map<std::string, ExprPtr> namedValues;
|
||||
|
||||
void addNamedValue(std::string n) {}
|
||||
void addNamedValue(std::string n, ExprPtr val) {}
|
||||
};
|
||||
typedef std::shared_ptr<SimpleField> SimpleFieldPtr;
|
||||
|
||||
|
||||
inline SimpleField::Attrs operator|(SimpleField::Attrs a, SimpleField::Attrs b)
|
||||
{
|
||||
return SimpleField::Attrs( int(a) | int(b) );
|
||||
}
|
||||
|
||||
|
||||
class ResourceDefinitions
|
||||
{
|
||||
public:
|
||||
ResourceDefinitions();
|
||||
};
|
||||
|
||||
#endif // RESOURCEDEFINITIONS_H
|
@ -49,6 +49,24 @@ static int readInt(const char *str)
|
||||
return x;
|
||||
}
|
||||
|
||||
static int readCharLit(const char *str)
|
||||
{
|
||||
const char *p = str + 1;
|
||||
const char *e = str + strlen(str) - 1;
|
||||
|
||||
if(e - p != 4)
|
||||
std::cout << "warning: CHAR LITERAL " << str << "\n";
|
||||
|
||||
int x = 0;
|
||||
while(p != e)
|
||||
{
|
||||
x <<= 8;
|
||||
x |= (*p) & 0xFF;
|
||||
++p;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
RezSymbol RezLexer::nextToken()
|
||||
{
|
||||
for(auto tok = nextWave(); tok != T_EOI && tok != T_EOF; tok = nextWave())
|
||||
@ -154,7 +172,7 @@ case T_ ## name: /*std::cout << #name << std::endl;*/ return RezParser::make_ ##
|
||||
{
|
||||
case T_INTLIT: return RezParser::make_INTLIT(readInt(tok.get_value().c_str()), loc);
|
||||
|
||||
case T_CHARLIT: return RezParser::make_CHARLIT(tok.get_value().c_str(), loc);
|
||||
case T_CHARLIT: return RezParser::make_CHARLIT(readCharLit(tok.get_value().c_str()), loc);
|
||||
case T_STRINGLIT: return RezParser::make_STRINGLIT(tok.get_value().c_str(), loc);
|
||||
|
||||
NOVAL_TOK(LEFTBRACE);
|
||||
|
112
Rez/RezParser.yy
112
Rez/RezParser.yy
@ -10,7 +10,7 @@
|
||||
%define parse.assert
|
||||
|
||||
%token<std::string> IDENTIFIER;
|
||||
%token<std::string> CHARLIT;
|
||||
%token<int> CHARLIT;
|
||||
%token<std::string> STRINGLIT;
|
||||
%token<int> INTLIT;
|
||||
|
||||
@ -83,6 +83,8 @@
|
||||
%param { RezLexer& lexer }
|
||||
|
||||
%code requires {
|
||||
#include "ResourceDefinitions.h"
|
||||
|
||||
#define YY_NULLPTR nullptr
|
||||
class RezLexer;
|
||||
}
|
||||
@ -120,14 +122,6 @@ rez : %empty
|
||||
| rez resource ";"
|
||||
;
|
||||
|
||||
simpletype : "boolean"
|
||||
| "bit" | "byte" | "word" | "integer" | "long" | "longint" | "rect"
|
||||
| "point"
|
||||
| "char"
|
||||
| "pstring" array_count_opt
|
||||
| "wstring" array_count_opt
|
||||
| "string" array_count_opt;
|
||||
| "bitstring" "[" expression "]";
|
||||
|
||||
type_definition : "type" type_spec "{" field_definitions "}"
|
||||
{ std::cout << "TYPE " << $2 << std::endl; }
|
||||
@ -135,9 +129,12 @@ type_definition : "type" type_spec "{" field_definitions "}"
|
||||
{ std::cout << "TYPE " << $2 << std::endl; }
|
||||
;
|
||||
|
||||
%type <std::string> type_spec;
|
||||
type_spec : CHARLIT { $$ = $1; }
|
||||
| CHARLIT "(" INTLIT ")" { $$ = $1; }
|
||||
%type <ResType> res_type;
|
||||
res_type : CHARLIT { $$ = ResType($1); } ;
|
||||
|
||||
%type <TypeSpec> type_spec;
|
||||
type_spec : res_type { $$ = TypeSpec($res_type); }
|
||||
| res_type "(" INTLIT ")" { $$ = TypeSpec($res_type, $INTLIT); }
|
||||
;
|
||||
|
||||
field_definitions : %empty
|
||||
@ -145,40 +142,78 @@ field_definitions : %empty
|
||||
| field_definitions ";"
|
||||
| field_definitions field_definition ";" ;
|
||||
|
||||
field_definition: simple_field_definition
|
||||
%type <FieldPtr> field_definition;
|
||||
field_definition: simple_field_definition { $$ = $1; }
|
||||
| array_definition
|
||||
| switch_definition
|
||||
| fill_statement
|
||||
| align_statement;
|
||||
|
||||
%type <SimpleFieldPtr> simple_field_definition;
|
||||
simple_field_definition: field_attributes simpletype array_count_opt value_spec_opt
|
||||
{
|
||||
$$ = std::make_shared<SimpleField>();
|
||||
$$->attrs = $field_attributes;
|
||||
$$->type = $simpletype;
|
||||
$$->arrayCount = $array_count_opt;
|
||||
$$->value = $value_spec_opt;
|
||||
}
|
||||
| simple_field_definition IDENTIFIER
|
||||
{ $$ = $1; $$->addNamedValue($IDENTIFIER); }
|
||||
| simple_field_definition IDENTIFIER "=" value
|
||||
{ $$ = $1; $$->addNamedValue($IDENTIFIER, $value); }
|
||||
| simple_field_definition "," IDENTIFIER
|
||||
{ $$ = $1; $$->addNamedValue($IDENTIFIER); }
|
||||
| simple_field_definition "," IDENTIFIER "=" value
|
||||
{ $$ = $1; $$->addNamedValue($IDENTIFIER, $value); }
|
||||
;
|
||||
|
||||
%type <ExprPtr> array_count array_count_opt value_spec_opt value ;
|
||||
%type <ExprPtr> expression expression1 expression2 ;
|
||||
%type <ExprPtr> expression3 expression4 expression5 expression6;
|
||||
%type <ExprPtr> expression7 expression8;
|
||||
|
||||
value_spec_opt : %empty { $$ = nullptr; } | "=" value { $$ = $2; } ;
|
||||
|
||||
%type <SimpleField::Type> simpletype;
|
||||
simpletype : "boolean" { $$ = SimpleField::Type::boolean; }
|
||||
| "byte" { $$ = SimpleField::Type::byte; }
|
||||
| "integer" { $$ = SimpleField::Type::integer; }
|
||||
| "longint" { $$ = SimpleField::Type::longint; }
|
||||
| "rect" { $$ = SimpleField::Type::rect; }
|
||||
| "point" { $$ = SimpleField::Type::point; }
|
||||
| "char" { $$ = SimpleField::Type::char_; }
|
||||
| "pstring" { $$ = SimpleField::Type::pstring; }
|
||||
| "wstring" { $$ = SimpleField::Type::wstring; }
|
||||
| "string" { $$ = SimpleField::Type::string; }
|
||||
| "bitstring" { $$ = SimpleField::Type::bitstring; }
|
||||
;
|
||||
|
||||
fill_statement : "fill" fill_unit array_count_opt;
|
||||
align_statement : "align" fill_unit;
|
||||
|
||||
fill_unit : "bit" | "byte" | "word" | "long";
|
||||
|
||||
simple_field_definition: field_attributes simpletype value_spec;
|
||||
|
||||
value_spec : %empty
|
||||
| named_values
|
||||
| "=" expression;
|
||||
|
||||
named_values: named_value
|
||||
| named_values "," named_value
|
||||
| named_values named_value;
|
||||
|
||||
named_value : IDENTIFIER
|
||||
| IDENTIFIER "=" expression ;
|
||||
|
||||
array_definition: array_attributes "array" array_name_opt array_count_opt "{" field_definitions "}" ;
|
||||
|
||||
array_count : "[" expression "]" ;
|
||||
array_count_opt : %empty | array_count ;
|
||||
array_count : "[" expression "]" { $$ = $2; }
|
||||
array_count_opt : %empty { $$ = nullptr; } | array_count;
|
||||
|
||||
array_name_opt : %empty | IDENTIFIER ;
|
||||
|
||||
array_attributes: %empty | "wide" ;
|
||||
field_attributes: %empty | field_attributes field_attribute;
|
||||
field_attribute : "hex" | "key" | "unsigned" | "literal";
|
||||
|
||||
%type <SimpleField::Attrs> field_attributes field_attribute;
|
||||
field_attributes: %empty { $$ = SimpleField::Attrs::none; }
|
||||
| field_attributes field_attribute { $$ = $1 | $2; }
|
||||
;
|
||||
|
||||
field_attribute : "hex" { $$ = SimpleField::Attrs::hex; }
|
||||
| "key" { $$ = SimpleField::Attrs::key; }
|
||||
| "unsigned" { $$ = SimpleField::Attrs::unsigned_; }
|
||||
| "literal" { $$ = SimpleField::Attrs::literal; }
|
||||
;
|
||||
|
||||
switch_definition: "switch" "{"
|
||||
switch_cases
|
||||
@ -206,6 +241,11 @@ expression
|
||||
;
|
||||
*/
|
||||
|
||||
value : expression
|
||||
| "{" resource_body "}"
|
||||
| STRINGLIT { $$ = std::make_shared<StringExpr>($1); }
|
||||
;
|
||||
|
||||
expression : expression1
|
||||
| expression "^" expression1
|
||||
;
|
||||
@ -243,20 +283,20 @@ expression7 : expression8
|
||||
| "~" expression7
|
||||
;
|
||||
|
||||
expression8 : INTLIT
|
||||
| CHARLIT
|
||||
| STRINGLIT
|
||||
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
|
||||
|
||||
| IDENTIFIER
|
||||
| IDENTIFIER "(" function_argument_list ")"
|
||||
| IDENTIFIER "[" function_argument_list1 "]"
|
||||
| "(" expression ")"
|
||||
| "{" resource_body "}"
|
||||
| "(" expression ")" { $$ = $2; }
|
||||
|
||||
;
|
||||
|
||||
function_argument_list : %empty | function_argument_list1 ;
|
||||
function_argument_list1 : expression | function_argument_list "," expression ;
|
||||
|
||||
resource: "resource" CHARLIT "(" function_argument_list ")" "{" resource_body "}"
|
||||
resource: "resource" res_type "(" function_argument_list ")" "{" resource_body "}"
|
||||
{ std::cout << "RESOURCE " << $2 << std::endl; }
|
||||
|
||||
resource_body : %empty | resource_body1 ;
|
||||
@ -266,6 +306,6 @@ resource_body1 : resource_item
|
||||
| resource_body1 ";"
|
||||
;
|
||||
|
||||
resource_item : expression | IDENTIFIER "{" resource_body "}" ;
|
||||
resource_item : value | IDENTIFIER "{" resource_body "}" ;
|
||||
|
||||
%%
|
||||
|
Loading…
Reference in New Issue
Block a user