diff --git a/Rez/CMakeLists.txt b/Rez/CMakeLists.txt index ae7c33bf55..c5e070d5ca 100644 --- a/Rez/CMakeLists.txt +++ b/Rez/CMakeLists.txt @@ -43,6 +43,9 @@ add_executable(Rez RezLexer.cc RezLexerWaveToken.h RezLexerNextToken.cc + + ResourceDefinitions.cc + ResourceDefinitions.h ) target_link_libraries(Rez ${Boost_LIBRARIES}) diff --git a/Rez/ResourceDefinitions.cc b/Rez/ResourceDefinitions.cc new file mode 100644 index 0000000000..6d0e481485 --- /dev/null +++ b/Rez/ResourceDefinitions.cc @@ -0,0 +1,27 @@ +#include "ResourceDefinitions.h" +#include + +ResourceDefinitions::ResourceDefinitions() +{ +} + + + +std::ostream &operator<<(std::ostream &out, ResType t) +{ + char c1 = static_cast((int)t >> 24); + char c2 = static_cast((int)t >> 16); + char c3 = static_cast((int)t >> 8); + char c4 = static_cast((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; +} diff --git a/Rez/ResourceDefinitions.h b/Rez/ResourceDefinitions.h new file mode 100644 index 0000000000..06c239c4e5 --- /dev/null +++ b/Rez/ResourceDefinitions.h @@ -0,0 +1,112 @@ +#ifndef RESOURCEDEFINITIONS_H +#define RESOURCEDEFINITIONS_H + +#include +#include +#include + +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 ExprPtr; + +class Field +{ +public: + virtual bool needsValue() { return true; } +}; +typedef std::shared_ptr 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 namedValues; + + void addNamedValue(std::string n) {} + void addNamedValue(std::string n, ExprPtr val) {} +}; +typedef std::shared_ptr 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 diff --git a/Rez/RezLexerNextToken.cc b/Rez/RezLexerNextToken.cc index f862edbf02..2297705ed4 100644 --- a/Rez/RezLexerNextToken.cc +++ b/Rez/RezLexerNextToken.cc @@ -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); diff --git a/Rez/RezParser.yy b/Rez/RezParser.yy index ed5dacad8e..d8005168ca 100644 --- a/Rez/RezParser.yy +++ b/Rez/RezParser.yy @@ -10,7 +10,7 @@ %define parse.assert %token IDENTIFIER; -%token CHARLIT; +%token CHARLIT; %token STRINGLIT; %token 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 type_spec; -type_spec : CHARLIT { $$ = $1; } - | CHARLIT "(" INTLIT ")" { $$ = $1; } +%type res_type; +res_type : CHARLIT { $$ = ResType($1); } ; + +%type 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 field_definition; +field_definition: simple_field_definition { $$ = $1; } | array_definition | switch_definition | fill_statement | align_statement; +%type simple_field_definition; +simple_field_definition: field_attributes simpletype array_count_opt value_spec_opt + { + $$ = std::make_shared(); + $$->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 array_count array_count_opt value_spec_opt value ; +%type expression expression1 expression2 ; +%type expression3 expression4 expression5 expression6; +%type expression7 expression8; + +value_spec_opt : %empty { $$ = nullptr; } | "=" value { $$ = $2; } ; + +%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 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($1); } + ; + expression : expression1 | expression "^" expression1 ; @@ -243,20 +283,20 @@ expression7 : expression8 | "~" expression7 ; -expression8 : INTLIT - | CHARLIT - | STRINGLIT +expression8 : INTLIT { $$ = std::make_shared($1); } + | CHARLIT { $$ = std::make_shared($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 "}" ; %%