[torque]: Implement structs
Struct are bundles of value types. They are essentially just shorthand for passing around a group of individually defined values. Struct types are declared like this: struct A { x: Smi; y: int32; } and can be constructed explicitly like this: A{0, 0} Structs can be used wherever other types are used (e.g. variables, parameters, return values) except for parameter/return types of builtins and runtime functions. Struct use field access notation to set/get their values like this: let a: A = A{0, 0}; let b: Smi = a.x; a.y = 0; Change-Id: I9fd36a6514c37882831256a49a50809c5db75b56 Reviewed-on: https://chromium-review.googlesource.com/1122133 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#54501}
This commit is contained in:
parent
16af1baac4
commit
1062ffb958
@ -190,9 +190,11 @@ unaryExpression
|
||||
| op=(PLUS | MINUS | BIT_NOT | NOT) unaryExpression;
|
||||
|
||||
locationExpression
|
||||
: IDENTIFIER genericSpecializationTypeList?
|
||||
: IDENTIFIER
|
||||
| locationExpression '.' IDENTIFIER
|
||||
| locationExpression '[' expression ']';
|
||||
| primaryExpression '.' IDENTIFIER
|
||||
| locationExpression '[' expression ']'
|
||||
| primaryExpression '[' expression ']';
|
||||
|
||||
incrementDecrement
|
||||
: INCREMENT locationExpression
|
||||
@ -206,14 +208,24 @@ assignment
|
||||
| locationExpression ((ASSIGNMENT | ASSIGNMENT_OPERATOR) expression)?;
|
||||
|
||||
assignmentExpression
|
||||
: primaryExpression
|
||||
: functionPointerExpression
|
||||
| assignment;
|
||||
|
||||
structExpression
|
||||
: IDENTIFIER '{' (expression (',' expression)*)? '}';
|
||||
|
||||
functionPointerExpression
|
||||
: primaryExpression
|
||||
| IDENTIFIER genericSpecializationTypeList?
|
||||
;
|
||||
|
||||
primaryExpression
|
||||
: helperCall
|
||||
| structExpression
|
||||
| DECIMAL_LITERAL
|
||||
| STRING_LITERAL
|
||||
| ('(' expression ')');
|
||||
| ('(' expression ')')
|
||||
;
|
||||
|
||||
forInitialization : variableDeclarationWithInitialization?;
|
||||
forLoop: FOR '(' forInitialization ';' expression ';' assignment ')' statementBlock;
|
||||
@ -266,6 +278,9 @@ statementBlock
|
||||
|
||||
helperBody : statementScope;
|
||||
|
||||
fieldDeclaration: IDENTIFIER ':' type ';';
|
||||
fieldListDeclaration: fieldDeclaration*;
|
||||
|
||||
extendsDeclaration: 'extends' IDENTIFIER;
|
||||
generatesDeclaration: 'generates' STRING_LITERAL;
|
||||
constexprDeclaration: 'constexpr' STRING_LITERAL;
|
||||
@ -280,9 +295,11 @@ genericSpecialization: IDENTIFIER genericSpecializationTypeList parameterList op
|
||||
macroDeclaration : ('operator' STRING_LITERAL)? MACRO IDENTIFIER optionalGenericTypeList parameterList optionalType optionalLabelList (helperBody | ';');
|
||||
externConstDeclaration : CONST IDENTIFIER ':' type generatesDeclaration ';';
|
||||
constDeclaration: CONST IDENTIFIER ':' type ASSIGNMENT expression ';';
|
||||
structDeclaration : 'struct' IDENTIFIER '{' fieldListDeclaration '}';
|
||||
|
||||
declaration
|
||||
: typeDeclaration
|
||||
: structDeclaration
|
||||
| typeDeclaration
|
||||
| typeAliasDeclaration
|
||||
| builtinDeclaration
|
||||
| genericSpecialization
|
||||
|
249
src/torque/Torque.interp
Normal file
249
src/torque/Torque.interp
Normal file
File diff suppressed because one or more lines are too long
154
src/torque/Torque.tokens
Normal file
154
src/torque/Torque.tokens
Normal file
@ -0,0 +1,154 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
T__14=15
|
||||
T__15=16
|
||||
T__16=17
|
||||
T__17=18
|
||||
T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
MACRO=22
|
||||
BUILTIN=23
|
||||
RUNTIME=24
|
||||
MODULE=25
|
||||
JAVASCRIPT=26
|
||||
DEFERRED=27
|
||||
IF=28
|
||||
FOR=29
|
||||
WHILE=30
|
||||
RETURN=31
|
||||
CONSTEXPR=32
|
||||
CONTINUE=33
|
||||
BREAK=34
|
||||
GOTO=35
|
||||
OTHERWISE=36
|
||||
TRY=37
|
||||
LABEL=38
|
||||
LABELS=39
|
||||
TAIL=40
|
||||
ISNT=41
|
||||
IS=42
|
||||
LET=43
|
||||
CONST=44
|
||||
EXTERN=45
|
||||
ASSERT_TOKEN=46
|
||||
CHECK_TOKEN=47
|
||||
UNREACHABLE_TOKEN=48
|
||||
DEBUG_TOKEN=49
|
||||
ASSIGNMENT=50
|
||||
ASSIGNMENT_OPERATOR=51
|
||||
EQUAL=52
|
||||
PLUS=53
|
||||
MINUS=54
|
||||
MULTIPLY=55
|
||||
DIVIDE=56
|
||||
MODULO=57
|
||||
BIT_OR=58
|
||||
BIT_AND=59
|
||||
BIT_NOT=60
|
||||
MAX=61
|
||||
MIN=62
|
||||
NOT_EQUAL=63
|
||||
LESS_THAN=64
|
||||
LESS_THAN_EQUAL=65
|
||||
GREATER_THAN=66
|
||||
GREATER_THAN_EQUAL=67
|
||||
SHIFT_LEFT=68
|
||||
SHIFT_RIGHT=69
|
||||
SHIFT_RIGHT_ARITHMETIC=70
|
||||
VARARGS=71
|
||||
EQUALITY_OPERATOR=72
|
||||
INCREMENT=73
|
||||
DECREMENT=74
|
||||
NOT=75
|
||||
STRING_LITERAL=76
|
||||
IDENTIFIER=77
|
||||
WS=78
|
||||
BLOCK_COMMENT=79
|
||||
LINE_COMMENT=80
|
||||
DECIMAL_LITERAL=81
|
||||
'('=1
|
||||
')'=2
|
||||
'=>'=3
|
||||
','=4
|
||||
':'=5
|
||||
'type'=6
|
||||
'?'=7
|
||||
'||'=8
|
||||
'&&'=9
|
||||
'.'=10
|
||||
'['=11
|
||||
']'=12
|
||||
'{'=13
|
||||
'}'=14
|
||||
';'=15
|
||||
'of'=16
|
||||
'else'=17
|
||||
'extends'=18
|
||||
'generates'=19
|
||||
'operator'=20
|
||||
'struct'=21
|
||||
'macro'=22
|
||||
'builtin'=23
|
||||
'runtime'=24
|
||||
'module'=25
|
||||
'javascript'=26
|
||||
'deferred'=27
|
||||
'if'=28
|
||||
'for'=29
|
||||
'while'=30
|
||||
'return'=31
|
||||
'constexpr'=32
|
||||
'continue'=33
|
||||
'break'=34
|
||||
'goto'=35
|
||||
'otherwise'=36
|
||||
'try'=37
|
||||
'label'=38
|
||||
'labels'=39
|
||||
'tail'=40
|
||||
'isnt'=41
|
||||
'is'=42
|
||||
'let'=43
|
||||
'const'=44
|
||||
'extern'=45
|
||||
'assert'=46
|
||||
'check'=47
|
||||
'unreachable'=48
|
||||
'debug'=49
|
||||
'='=50
|
||||
'=='=52
|
||||
'+'=53
|
||||
'-'=54
|
||||
'*'=55
|
||||
'/'=56
|
||||
'%'=57
|
||||
'|'=58
|
||||
'&'=59
|
||||
'~'=60
|
||||
'max'=61
|
||||
'min'=62
|
||||
'!='=63
|
||||
'<'=64
|
||||
'<='=65
|
||||
'>'=66
|
||||
'>='=67
|
||||
'<<'=68
|
||||
'>>'=69
|
||||
'>>>'=70
|
||||
'...'=71
|
||||
'++'=73
|
||||
'--'=74
|
||||
'!'=75
|
@ -141,6 +141,16 @@ class TorqueBaseListener : public TorqueListener {
|
||||
void exitAssignmentExpression(
|
||||
TorqueParser::AssignmentExpressionContext* /*ctx*/) override {}
|
||||
|
||||
void enterStructExpression(
|
||||
TorqueParser::StructExpressionContext* /*ctx*/) override {}
|
||||
void exitStructExpression(
|
||||
TorqueParser::StructExpressionContext* /*ctx*/) override {}
|
||||
|
||||
void enterFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* /*ctx*/) override {}
|
||||
void exitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* /*ctx*/) override {}
|
||||
|
||||
void enterPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* /*ctx*/) override {}
|
||||
void exitPrimaryExpression(
|
||||
@ -263,6 +273,16 @@ class TorqueBaseListener : public TorqueListener {
|
||||
void enterHelperBody(TorqueParser::HelperBodyContext* /*ctx*/) override {}
|
||||
void exitHelperBody(TorqueParser::HelperBodyContext* /*ctx*/) override {}
|
||||
|
||||
void enterFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* /*ctx*/) override {}
|
||||
void exitFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* /*ctx*/) override {}
|
||||
|
||||
void enterFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* /*ctx*/) override {}
|
||||
void exitFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* /*ctx*/) override {}
|
||||
|
||||
void enterExtendsDeclaration(
|
||||
TorqueParser::ExtendsDeclarationContext* /*ctx*/) override {}
|
||||
void exitExtendsDeclaration(
|
||||
@ -328,6 +348,11 @@ class TorqueBaseListener : public TorqueListener {
|
||||
void exitConstDeclaration(
|
||||
TorqueParser::ConstDeclarationContext* /*ctx*/) override {}
|
||||
|
||||
void enterStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* /*ctx*/) override {}
|
||||
void exitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* /*ctx*/) override {}
|
||||
|
||||
void enterDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {}
|
||||
void exitDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {}
|
||||
|
||||
|
@ -148,6 +148,16 @@ class TorqueBaseVisitor : public TorqueVisitor {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitStructExpression(
|
||||
TorqueParser::StructExpressionContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
@ -281,6 +291,16 @@ class TorqueBaseVisitor : public TorqueVisitor {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitExtendsDeclaration(
|
||||
TorqueParser::ExtendsDeclarationContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
@ -346,6 +366,11 @@ class TorqueBaseVisitor : public TorqueVisitor {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
antlrcpp::Any visitDeclaration(
|
||||
TorqueParser::DeclarationContext* ctx) override {
|
||||
return visitChildren(ctx);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,66 +33,67 @@ class TorqueLexer : public antlr4::Lexer {
|
||||
T__17 = 18,
|
||||
T__18 = 19,
|
||||
T__19 = 20,
|
||||
MACRO = 21,
|
||||
BUILTIN = 22,
|
||||
RUNTIME = 23,
|
||||
MODULE = 24,
|
||||
JAVASCRIPT = 25,
|
||||
DEFERRED = 26,
|
||||
IF = 27,
|
||||
FOR = 28,
|
||||
WHILE = 29,
|
||||
RETURN = 30,
|
||||
CONSTEXPR = 31,
|
||||
CONTINUE = 32,
|
||||
BREAK = 33,
|
||||
GOTO = 34,
|
||||
OTHERWISE = 35,
|
||||
TRY = 36,
|
||||
LABEL = 37,
|
||||
LABELS = 38,
|
||||
TAIL = 39,
|
||||
ISNT = 40,
|
||||
IS = 41,
|
||||
LET = 42,
|
||||
CONST = 43,
|
||||
EXTERN = 44,
|
||||
ASSERT_TOKEN = 45,
|
||||
CHECK_TOKEN = 46,
|
||||
UNREACHABLE_TOKEN = 47,
|
||||
DEBUG_TOKEN = 48,
|
||||
ASSIGNMENT = 49,
|
||||
ASSIGNMENT_OPERATOR = 50,
|
||||
EQUAL = 51,
|
||||
PLUS = 52,
|
||||
MINUS = 53,
|
||||
MULTIPLY = 54,
|
||||
DIVIDE = 55,
|
||||
MODULO = 56,
|
||||
BIT_OR = 57,
|
||||
BIT_AND = 58,
|
||||
BIT_NOT = 59,
|
||||
MAX = 60,
|
||||
MIN = 61,
|
||||
NOT_EQUAL = 62,
|
||||
LESS_THAN = 63,
|
||||
LESS_THAN_EQUAL = 64,
|
||||
GREATER_THAN = 65,
|
||||
GREATER_THAN_EQUAL = 66,
|
||||
SHIFT_LEFT = 67,
|
||||
SHIFT_RIGHT = 68,
|
||||
SHIFT_RIGHT_ARITHMETIC = 69,
|
||||
VARARGS = 70,
|
||||
EQUALITY_OPERATOR = 71,
|
||||
INCREMENT = 72,
|
||||
DECREMENT = 73,
|
||||
NOT = 74,
|
||||
STRING_LITERAL = 75,
|
||||
IDENTIFIER = 76,
|
||||
WS = 77,
|
||||
BLOCK_COMMENT = 78,
|
||||
LINE_COMMENT = 79,
|
||||
DECIMAL_LITERAL = 80
|
||||
T__20 = 21,
|
||||
MACRO = 22,
|
||||
BUILTIN = 23,
|
||||
RUNTIME = 24,
|
||||
MODULE = 25,
|
||||
JAVASCRIPT = 26,
|
||||
DEFERRED = 27,
|
||||
IF = 28,
|
||||
FOR = 29,
|
||||
WHILE = 30,
|
||||
RETURN = 31,
|
||||
CONSTEXPR = 32,
|
||||
CONTINUE = 33,
|
||||
BREAK = 34,
|
||||
GOTO = 35,
|
||||
OTHERWISE = 36,
|
||||
TRY = 37,
|
||||
LABEL = 38,
|
||||
LABELS = 39,
|
||||
TAIL = 40,
|
||||
ISNT = 41,
|
||||
IS = 42,
|
||||
LET = 43,
|
||||
CONST = 44,
|
||||
EXTERN = 45,
|
||||
ASSERT_TOKEN = 46,
|
||||
CHECK_TOKEN = 47,
|
||||
UNREACHABLE_TOKEN = 48,
|
||||
DEBUG_TOKEN = 49,
|
||||
ASSIGNMENT = 50,
|
||||
ASSIGNMENT_OPERATOR = 51,
|
||||
EQUAL = 52,
|
||||
PLUS = 53,
|
||||
MINUS = 54,
|
||||
MULTIPLY = 55,
|
||||
DIVIDE = 56,
|
||||
MODULO = 57,
|
||||
BIT_OR = 58,
|
||||
BIT_AND = 59,
|
||||
BIT_NOT = 60,
|
||||
MAX = 61,
|
||||
MIN = 62,
|
||||
NOT_EQUAL = 63,
|
||||
LESS_THAN = 64,
|
||||
LESS_THAN_EQUAL = 65,
|
||||
GREATER_THAN = 66,
|
||||
GREATER_THAN_EQUAL = 67,
|
||||
SHIFT_LEFT = 68,
|
||||
SHIFT_RIGHT = 69,
|
||||
SHIFT_RIGHT_ARITHMETIC = 70,
|
||||
VARARGS = 71,
|
||||
EQUALITY_OPERATOR = 72,
|
||||
INCREMENT = 73,
|
||||
DECREMENT = 74,
|
||||
NOT = 75,
|
||||
STRING_LITERAL = 76,
|
||||
IDENTIFIER = 77,
|
||||
WS = 78,
|
||||
BLOCK_COMMENT = 79,
|
||||
LINE_COMMENT = 80,
|
||||
DECIMAL_LITERAL = 81
|
||||
};
|
||||
|
||||
explicit TorqueLexer(antlr4::CharStream* input);
|
||||
|
264
src/torque/TorqueLexer.interp
Normal file
264
src/torque/TorqueLexer.interp
Normal file
File diff suppressed because one or more lines are too long
154
src/torque/TorqueLexer.tokens
Normal file
154
src/torque/TorqueLexer.tokens
Normal file
@ -0,0 +1,154 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
T__14=15
|
||||
T__15=16
|
||||
T__16=17
|
||||
T__17=18
|
||||
T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
MACRO=22
|
||||
BUILTIN=23
|
||||
RUNTIME=24
|
||||
MODULE=25
|
||||
JAVASCRIPT=26
|
||||
DEFERRED=27
|
||||
IF=28
|
||||
FOR=29
|
||||
WHILE=30
|
||||
RETURN=31
|
||||
CONSTEXPR=32
|
||||
CONTINUE=33
|
||||
BREAK=34
|
||||
GOTO=35
|
||||
OTHERWISE=36
|
||||
TRY=37
|
||||
LABEL=38
|
||||
LABELS=39
|
||||
TAIL=40
|
||||
ISNT=41
|
||||
IS=42
|
||||
LET=43
|
||||
CONST=44
|
||||
EXTERN=45
|
||||
ASSERT_TOKEN=46
|
||||
CHECK_TOKEN=47
|
||||
UNREACHABLE_TOKEN=48
|
||||
DEBUG_TOKEN=49
|
||||
ASSIGNMENT=50
|
||||
ASSIGNMENT_OPERATOR=51
|
||||
EQUAL=52
|
||||
PLUS=53
|
||||
MINUS=54
|
||||
MULTIPLY=55
|
||||
DIVIDE=56
|
||||
MODULO=57
|
||||
BIT_OR=58
|
||||
BIT_AND=59
|
||||
BIT_NOT=60
|
||||
MAX=61
|
||||
MIN=62
|
||||
NOT_EQUAL=63
|
||||
LESS_THAN=64
|
||||
LESS_THAN_EQUAL=65
|
||||
GREATER_THAN=66
|
||||
GREATER_THAN_EQUAL=67
|
||||
SHIFT_LEFT=68
|
||||
SHIFT_RIGHT=69
|
||||
SHIFT_RIGHT_ARITHMETIC=70
|
||||
VARARGS=71
|
||||
EQUALITY_OPERATOR=72
|
||||
INCREMENT=73
|
||||
DECREMENT=74
|
||||
NOT=75
|
||||
STRING_LITERAL=76
|
||||
IDENTIFIER=77
|
||||
WS=78
|
||||
BLOCK_COMMENT=79
|
||||
LINE_COMMENT=80
|
||||
DECIMAL_LITERAL=81
|
||||
'('=1
|
||||
')'=2
|
||||
'=>'=3
|
||||
','=4
|
||||
':'=5
|
||||
'type'=6
|
||||
'?'=7
|
||||
'||'=8
|
||||
'&&'=9
|
||||
'.'=10
|
||||
'['=11
|
||||
']'=12
|
||||
'{'=13
|
||||
'}'=14
|
||||
';'=15
|
||||
'of'=16
|
||||
'else'=17
|
||||
'extends'=18
|
||||
'generates'=19
|
||||
'operator'=20
|
||||
'struct'=21
|
||||
'macro'=22
|
||||
'builtin'=23
|
||||
'runtime'=24
|
||||
'module'=25
|
||||
'javascript'=26
|
||||
'deferred'=27
|
||||
'if'=28
|
||||
'for'=29
|
||||
'while'=30
|
||||
'return'=31
|
||||
'constexpr'=32
|
||||
'continue'=33
|
||||
'break'=34
|
||||
'goto'=35
|
||||
'otherwise'=36
|
||||
'try'=37
|
||||
'label'=38
|
||||
'labels'=39
|
||||
'tail'=40
|
||||
'isnt'=41
|
||||
'is'=42
|
||||
'let'=43
|
||||
'const'=44
|
||||
'extern'=45
|
||||
'assert'=46
|
||||
'check'=47
|
||||
'unreachable'=48
|
||||
'debug'=49
|
||||
'='=50
|
||||
'=='=52
|
||||
'+'=53
|
||||
'-'=54
|
||||
'*'=55
|
||||
'/'=56
|
||||
'%'=57
|
||||
'|'=58
|
||||
'&'=59
|
||||
'~'=60
|
||||
'max'=61
|
||||
'min'=62
|
||||
'!='=63
|
||||
'<'=64
|
||||
'<='=65
|
||||
'>'=66
|
||||
'>='=67
|
||||
'<<'=68
|
||||
'>>'=69
|
||||
'>>>'=70
|
||||
'...'=71
|
||||
'++'=73
|
||||
'--'=74
|
||||
'!'=75
|
@ -137,6 +137,16 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
|
||||
virtual void exitAssignmentExpression(
|
||||
TorqueParser::AssignmentExpressionContext* ctx) = 0;
|
||||
|
||||
virtual void enterStructExpression(
|
||||
TorqueParser::StructExpressionContext* ctx) = 0;
|
||||
virtual void exitStructExpression(
|
||||
TorqueParser::StructExpressionContext* ctx) = 0;
|
||||
|
||||
virtual void enterFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* ctx) = 0;
|
||||
virtual void exitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* ctx) = 0;
|
||||
|
||||
virtual void enterPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* ctx) = 0;
|
||||
virtual void exitPrimaryExpression(
|
||||
@ -248,6 +258,16 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
|
||||
virtual void enterHelperBody(TorqueParser::HelperBodyContext* ctx) = 0;
|
||||
virtual void exitHelperBody(TorqueParser::HelperBodyContext* ctx) = 0;
|
||||
|
||||
virtual void enterFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* ctx) = 0;
|
||||
virtual void exitFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* ctx) = 0;
|
||||
|
||||
virtual void enterFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* ctx) = 0;
|
||||
virtual void exitFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* ctx) = 0;
|
||||
|
||||
virtual void enterExtendsDeclaration(
|
||||
TorqueParser::ExtendsDeclarationContext* ctx) = 0;
|
||||
virtual void exitExtendsDeclaration(
|
||||
@ -311,6 +331,11 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
|
||||
virtual void exitConstDeclaration(
|
||||
TorqueParser::ConstDeclarationContext* ctx) = 0;
|
||||
|
||||
virtual void enterStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* ctx) = 0;
|
||||
virtual void exitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* ctx) = 0;
|
||||
|
||||
virtual void enterDeclaration(TorqueParser::DeclarationContext* ctx) = 0;
|
||||
virtual void exitDeclaration(TorqueParser::DeclarationContext* ctx) = 0;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,66 +33,67 @@ class TorqueParser : public antlr4::Parser {
|
||||
T__17 = 18,
|
||||
T__18 = 19,
|
||||
T__19 = 20,
|
||||
MACRO = 21,
|
||||
BUILTIN = 22,
|
||||
RUNTIME = 23,
|
||||
MODULE = 24,
|
||||
JAVASCRIPT = 25,
|
||||
DEFERRED = 26,
|
||||
IF = 27,
|
||||
FOR = 28,
|
||||
WHILE = 29,
|
||||
RETURN = 30,
|
||||
CONSTEXPR = 31,
|
||||
CONTINUE = 32,
|
||||
BREAK = 33,
|
||||
GOTO = 34,
|
||||
OTHERWISE = 35,
|
||||
TRY = 36,
|
||||
LABEL = 37,
|
||||
LABELS = 38,
|
||||
TAIL = 39,
|
||||
ISNT = 40,
|
||||
IS = 41,
|
||||
LET = 42,
|
||||
CONST = 43,
|
||||
EXTERN = 44,
|
||||
ASSERT_TOKEN = 45,
|
||||
CHECK_TOKEN = 46,
|
||||
UNREACHABLE_TOKEN = 47,
|
||||
DEBUG_TOKEN = 48,
|
||||
ASSIGNMENT = 49,
|
||||
ASSIGNMENT_OPERATOR = 50,
|
||||
EQUAL = 51,
|
||||
PLUS = 52,
|
||||
MINUS = 53,
|
||||
MULTIPLY = 54,
|
||||
DIVIDE = 55,
|
||||
MODULO = 56,
|
||||
BIT_OR = 57,
|
||||
BIT_AND = 58,
|
||||
BIT_NOT = 59,
|
||||
MAX = 60,
|
||||
MIN = 61,
|
||||
NOT_EQUAL = 62,
|
||||
LESS_THAN = 63,
|
||||
LESS_THAN_EQUAL = 64,
|
||||
GREATER_THAN = 65,
|
||||
GREATER_THAN_EQUAL = 66,
|
||||
SHIFT_LEFT = 67,
|
||||
SHIFT_RIGHT = 68,
|
||||
SHIFT_RIGHT_ARITHMETIC = 69,
|
||||
VARARGS = 70,
|
||||
EQUALITY_OPERATOR = 71,
|
||||
INCREMENT = 72,
|
||||
DECREMENT = 73,
|
||||
NOT = 74,
|
||||
STRING_LITERAL = 75,
|
||||
IDENTIFIER = 76,
|
||||
WS = 77,
|
||||
BLOCK_COMMENT = 78,
|
||||
LINE_COMMENT = 79,
|
||||
DECIMAL_LITERAL = 80
|
||||
T__20 = 21,
|
||||
MACRO = 22,
|
||||
BUILTIN = 23,
|
||||
RUNTIME = 24,
|
||||
MODULE = 25,
|
||||
JAVASCRIPT = 26,
|
||||
DEFERRED = 27,
|
||||
IF = 28,
|
||||
FOR = 29,
|
||||
WHILE = 30,
|
||||
RETURN = 31,
|
||||
CONSTEXPR = 32,
|
||||
CONTINUE = 33,
|
||||
BREAK = 34,
|
||||
GOTO = 35,
|
||||
OTHERWISE = 36,
|
||||
TRY = 37,
|
||||
LABEL = 38,
|
||||
LABELS = 39,
|
||||
TAIL = 40,
|
||||
ISNT = 41,
|
||||
IS = 42,
|
||||
LET = 43,
|
||||
CONST = 44,
|
||||
EXTERN = 45,
|
||||
ASSERT_TOKEN = 46,
|
||||
CHECK_TOKEN = 47,
|
||||
UNREACHABLE_TOKEN = 48,
|
||||
DEBUG_TOKEN = 49,
|
||||
ASSIGNMENT = 50,
|
||||
ASSIGNMENT_OPERATOR = 51,
|
||||
EQUAL = 52,
|
||||
PLUS = 53,
|
||||
MINUS = 54,
|
||||
MULTIPLY = 55,
|
||||
DIVIDE = 56,
|
||||
MODULO = 57,
|
||||
BIT_OR = 58,
|
||||
BIT_AND = 59,
|
||||
BIT_NOT = 60,
|
||||
MAX = 61,
|
||||
MIN = 62,
|
||||
NOT_EQUAL = 63,
|
||||
LESS_THAN = 64,
|
||||
LESS_THAN_EQUAL = 65,
|
||||
GREATER_THAN = 66,
|
||||
GREATER_THAN_EQUAL = 67,
|
||||
SHIFT_LEFT = 68,
|
||||
SHIFT_RIGHT = 69,
|
||||
SHIFT_RIGHT_ARITHMETIC = 70,
|
||||
VARARGS = 71,
|
||||
EQUALITY_OPERATOR = 72,
|
||||
INCREMENT = 73,
|
||||
DECREMENT = 74,
|
||||
NOT = 75,
|
||||
STRING_LITERAL = 76,
|
||||
IDENTIFIER = 77,
|
||||
WS = 78,
|
||||
BLOCK_COMMENT = 79,
|
||||
LINE_COMMENT = 80,
|
||||
DECIMAL_LITERAL = 81
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -123,50 +124,55 @@ class TorqueParser : public antlr4::Parser {
|
||||
RuleIncrementDecrement = 24,
|
||||
RuleAssignment = 25,
|
||||
RuleAssignmentExpression = 26,
|
||||
RulePrimaryExpression = 27,
|
||||
RuleForInitialization = 28,
|
||||
RuleForLoop = 29,
|
||||
RuleRangeSpecifier = 30,
|
||||
RuleForOfRange = 31,
|
||||
RuleForOfLoop = 32,
|
||||
RuleArgument = 33,
|
||||
RuleArgumentList = 34,
|
||||
RuleHelperCall = 35,
|
||||
RuleLabelReference = 36,
|
||||
RuleVariableDeclaration = 37,
|
||||
RuleVariableDeclarationWithInitialization = 38,
|
||||
RuleHelperCallStatement = 39,
|
||||
RuleExpressionStatement = 40,
|
||||
RuleIfStatement = 41,
|
||||
RuleWhileLoop = 42,
|
||||
RuleReturnStatement = 43,
|
||||
RuleBreakStatement = 44,
|
||||
RuleContinueStatement = 45,
|
||||
RuleGotoStatement = 46,
|
||||
RuleHandlerWithStatement = 47,
|
||||
RuleTryLabelStatement = 48,
|
||||
RuleDiagnosticStatement = 49,
|
||||
RuleStatement = 50,
|
||||
RuleStatementList = 51,
|
||||
RuleStatementScope = 52,
|
||||
RuleStatementBlock = 53,
|
||||
RuleHelperBody = 54,
|
||||
RuleExtendsDeclaration = 55,
|
||||
RuleGeneratesDeclaration = 56,
|
||||
RuleConstexprDeclaration = 57,
|
||||
RuleTypeDeclaration = 58,
|
||||
RuleTypeAliasDeclaration = 59,
|
||||
RuleExternalBuiltin = 60,
|
||||
RuleExternalMacro = 61,
|
||||
RuleExternalRuntime = 62,
|
||||
RuleBuiltinDeclaration = 63,
|
||||
RuleGenericSpecialization = 64,
|
||||
RuleMacroDeclaration = 65,
|
||||
RuleExternConstDeclaration = 66,
|
||||
RuleConstDeclaration = 67,
|
||||
RuleDeclaration = 68,
|
||||
RuleModuleDeclaration = 69,
|
||||
RuleFile = 70
|
||||
RuleStructExpression = 27,
|
||||
RuleFunctionPointerExpression = 28,
|
||||
RulePrimaryExpression = 29,
|
||||
RuleForInitialization = 30,
|
||||
RuleForLoop = 31,
|
||||
RuleRangeSpecifier = 32,
|
||||
RuleForOfRange = 33,
|
||||
RuleForOfLoop = 34,
|
||||
RuleArgument = 35,
|
||||
RuleArgumentList = 36,
|
||||
RuleHelperCall = 37,
|
||||
RuleLabelReference = 38,
|
||||
RuleVariableDeclaration = 39,
|
||||
RuleVariableDeclarationWithInitialization = 40,
|
||||
RuleHelperCallStatement = 41,
|
||||
RuleExpressionStatement = 42,
|
||||
RuleIfStatement = 43,
|
||||
RuleWhileLoop = 44,
|
||||
RuleReturnStatement = 45,
|
||||
RuleBreakStatement = 46,
|
||||
RuleContinueStatement = 47,
|
||||
RuleGotoStatement = 48,
|
||||
RuleHandlerWithStatement = 49,
|
||||
RuleTryLabelStatement = 50,
|
||||
RuleDiagnosticStatement = 51,
|
||||
RuleStatement = 52,
|
||||
RuleStatementList = 53,
|
||||
RuleStatementScope = 54,
|
||||
RuleStatementBlock = 55,
|
||||
RuleHelperBody = 56,
|
||||
RuleFieldDeclaration = 57,
|
||||
RuleFieldListDeclaration = 58,
|
||||
RuleExtendsDeclaration = 59,
|
||||
RuleGeneratesDeclaration = 60,
|
||||
RuleConstexprDeclaration = 61,
|
||||
RuleTypeDeclaration = 62,
|
||||
RuleTypeAliasDeclaration = 63,
|
||||
RuleExternalBuiltin = 64,
|
||||
RuleExternalMacro = 65,
|
||||
RuleExternalRuntime = 66,
|
||||
RuleBuiltinDeclaration = 67,
|
||||
RuleGenericSpecialization = 68,
|
||||
RuleMacroDeclaration = 69,
|
||||
RuleExternConstDeclaration = 70,
|
||||
RuleConstDeclaration = 71,
|
||||
RuleStructDeclaration = 72,
|
||||
RuleDeclaration = 73,
|
||||
RuleModuleDeclaration = 74,
|
||||
RuleFile = 75
|
||||
};
|
||||
|
||||
explicit TorqueParser(antlr4::TokenStream* input);
|
||||
@ -207,6 +213,8 @@ class TorqueParser : public antlr4::Parser {
|
||||
class IncrementDecrementContext;
|
||||
class AssignmentContext;
|
||||
class AssignmentExpressionContext;
|
||||
class StructExpressionContext;
|
||||
class FunctionPointerExpressionContext;
|
||||
class PrimaryExpressionContext;
|
||||
class ForInitializationContext;
|
||||
class ForLoopContext;
|
||||
@ -235,6 +243,8 @@ class TorqueParser : public antlr4::Parser {
|
||||
class StatementScopeContext;
|
||||
class StatementBlockContext;
|
||||
class HelperBodyContext;
|
||||
class FieldDeclarationContext;
|
||||
class FieldListDeclarationContext;
|
||||
class ExtendsDeclarationContext;
|
||||
class GeneratesDeclarationContext;
|
||||
class ConstexprDeclarationContext;
|
||||
@ -248,6 +258,7 @@ class TorqueParser : public antlr4::Parser {
|
||||
class MacroDeclarationContext;
|
||||
class ExternConstDeclarationContext;
|
||||
class ConstDeclarationContext;
|
||||
class StructDeclarationContext;
|
||||
class DeclarationContext;
|
||||
class ModuleDeclarationContext;
|
||||
class FileContext;
|
||||
@ -658,9 +669,9 @@ class TorqueParser : public antlr4::Parser {
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
antlr4::tree::TerminalNode* IDENTIFIER();
|
||||
GenericSpecializationTypeListContext* genericSpecializationTypeList();
|
||||
LocationExpressionContext* locationExpression();
|
||||
PrimaryExpressionContext* primaryExpression();
|
||||
ExpressionContext* expression();
|
||||
LocationExpressionContext* locationExpression();
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
@ -711,7 +722,7 @@ class TorqueParser : public antlr4::Parser {
|
||||
AssignmentExpressionContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
PrimaryExpressionContext* primaryExpression();
|
||||
FunctionPointerExpressionContext* functionPointerExpression();
|
||||
AssignmentContext* assignment();
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
@ -722,12 +733,47 @@ class TorqueParser : public antlr4::Parser {
|
||||
|
||||
AssignmentExpressionContext* assignmentExpression();
|
||||
|
||||
class StructExpressionContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
StructExpressionContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
antlr4::tree::TerminalNode* IDENTIFIER();
|
||||
std::vector<ExpressionContext*> expression();
|
||||
ExpressionContext* expression(size_t i);
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
|
||||
antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor* visitor) override;
|
||||
};
|
||||
|
||||
StructExpressionContext* structExpression();
|
||||
|
||||
class FunctionPointerExpressionContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
FunctionPointerExpressionContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
PrimaryExpressionContext* primaryExpression();
|
||||
antlr4::tree::TerminalNode* IDENTIFIER();
|
||||
GenericSpecializationTypeListContext* genericSpecializationTypeList();
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
|
||||
antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor* visitor) override;
|
||||
};
|
||||
|
||||
FunctionPointerExpressionContext* functionPointerExpression();
|
||||
|
||||
class PrimaryExpressionContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
PrimaryExpressionContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
HelperCallContext* helperCall();
|
||||
StructExpressionContext* structExpression();
|
||||
antlr4::tree::TerminalNode* DECIMAL_LITERAL();
|
||||
antlr4::tree::TerminalNode* STRING_LITERAL();
|
||||
ExpressionContext* expression();
|
||||
@ -1196,6 +1242,38 @@ class TorqueParser : public antlr4::Parser {
|
||||
|
||||
HelperBodyContext* helperBody();
|
||||
|
||||
class FieldDeclarationContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
FieldDeclarationContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
antlr4::tree::TerminalNode* IDENTIFIER();
|
||||
TypeContext* type();
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
|
||||
antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor* visitor) override;
|
||||
};
|
||||
|
||||
FieldDeclarationContext* fieldDeclaration();
|
||||
|
||||
class FieldListDeclarationContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
FieldListDeclarationContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
std::vector<FieldDeclarationContext*> fieldDeclaration();
|
||||
FieldDeclarationContext* fieldDeclaration(size_t i);
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
|
||||
antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor* visitor) override;
|
||||
};
|
||||
|
||||
FieldListDeclarationContext* fieldListDeclaration();
|
||||
|
||||
class ExtendsDeclarationContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
ExtendsDeclarationContext(antlr4::ParserRuleContext* parent,
|
||||
@ -1437,10 +1515,27 @@ class TorqueParser : public antlr4::Parser {
|
||||
|
||||
ConstDeclarationContext* constDeclaration();
|
||||
|
||||
class StructDeclarationContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
StructDeclarationContext(antlr4::ParserRuleContext* parent,
|
||||
size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
antlr4::tree::TerminalNode* IDENTIFIER();
|
||||
FieldListDeclarationContext* fieldListDeclaration();
|
||||
|
||||
void enterRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
void exitRule(antlr4::tree::ParseTreeListener* listener) override;
|
||||
|
||||
antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor* visitor) override;
|
||||
};
|
||||
|
||||
StructDeclarationContext* structDeclaration();
|
||||
|
||||
class DeclarationContext : public antlr4::ParserRuleContext {
|
||||
public:
|
||||
DeclarationContext(antlr4::ParserRuleContext* parent, size_t invokingState);
|
||||
size_t getRuleIndex() const override;
|
||||
StructDeclarationContext* structDeclaration();
|
||||
TypeDeclarationContext* typeDeclaration();
|
||||
TypeAliasDeclarationContext* typeAliasDeclaration();
|
||||
BuiltinDeclarationContext* builtinDeclaration();
|
||||
|
@ -100,6 +100,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
|
||||
virtual antlrcpp::Any visitAssignmentExpression(
|
||||
TorqueParser::AssignmentExpressionContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitStructExpression(
|
||||
TorqueParser::StructExpressionContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* context) = 0;
|
||||
|
||||
@ -183,6 +189,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
|
||||
virtual antlrcpp::Any visitHelperBody(
|
||||
TorqueParser::HelperBodyContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitFieldDeclaration(
|
||||
TorqueParser::FieldDeclarationContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitFieldListDeclaration(
|
||||
TorqueParser::FieldListDeclarationContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitExtendsDeclaration(
|
||||
TorqueParser::ExtendsDeclarationContext* context) = 0;
|
||||
|
||||
@ -222,6 +234,9 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
|
||||
virtual antlrcpp::Any visitConstDeclaration(
|
||||
TorqueParser::ConstDeclarationContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* context) = 0;
|
||||
|
||||
virtual antlrcpp::Any visitDeclaration(
|
||||
TorqueParser::DeclarationContext* context) = 0;
|
||||
|
||||
|
@ -545,6 +545,21 @@ antlrcpp::Any AstGenerator::visitTryLabelStatement(
|
||||
return implicit_cast<Statement*>(result);
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* context) {
|
||||
if (context->IDENTIFIER()) {
|
||||
std::vector<TypeExpression*> templateArguments;
|
||||
if (context->genericSpecializationTypeList()) {
|
||||
templateArguments =
|
||||
GetTypeVector(context->genericSpecializationTypeList()->typeList());
|
||||
}
|
||||
return implicit_cast<Expression*>(RegisterNode(new IdentifierExpression{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
|
||||
std::move(templateArguments)}));
|
||||
}
|
||||
return context->primaryExpression()->accept(this);
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* context) {
|
||||
if (auto* e = context->helperCall()) return e->accept(this);
|
||||
@ -554,9 +569,23 @@ antlrcpp::Any AstGenerator::visitPrimaryExpression(
|
||||
if (auto* e = context->STRING_LITERAL())
|
||||
return implicit_cast<Expression*>(RegisterNode(
|
||||
new StringLiteralExpression{Pos(context), e->getSymbol()->getText()}));
|
||||
if (context->structExpression()) {
|
||||
return context->structExpression()->accept(this);
|
||||
}
|
||||
return context->expression()->accept(this);
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitStructExpression(
|
||||
TorqueParser::StructExpressionContext* context) {
|
||||
std::vector<Expression*> expressions;
|
||||
for (auto& e : context->expression()) {
|
||||
expressions.push_back(e->accept(this).as<Expression*>());
|
||||
}
|
||||
return implicit_cast<Expression*>(RegisterNode(new StructExpression{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
|
||||
expressions}));
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitAssignment(
|
||||
TorqueParser::AssignmentContext* context) {
|
||||
if (auto* e = context->incrementDecrement()) return e->accept(this);
|
||||
@ -589,25 +618,23 @@ antlrcpp::Any AstGenerator::visitIncrementDecrement(
|
||||
|
||||
antlrcpp::Any AstGenerator::visitLocationExpression(
|
||||
TorqueParser::LocationExpressionContext* context) {
|
||||
if (auto* l = context->locationExpression()) {
|
||||
Expression* location = l->accept(this).as<Expression*>();
|
||||
if (auto* e = context->expression()) {
|
||||
return implicit_cast<Expression*>(
|
||||
RegisterNode(new ElementAccessExpression{
|
||||
Pos(context), location, e->accept(this).as<Expression*>()}));
|
||||
}
|
||||
return implicit_cast<Expression*>(RegisterNode(new FieldAccessExpression{
|
||||
Pos(context), location,
|
||||
context->IDENTIFIER()->getSymbol()->getText()}));
|
||||
Expression* location = nullptr;
|
||||
if (auto* p = context->primaryExpression()) {
|
||||
location = p->accept(this).as<Expression*>();
|
||||
} else if (auto* l = context->locationExpression()) {
|
||||
location = l->accept(this).as<Expression*>();
|
||||
} else {
|
||||
return implicit_cast<Expression*>(RegisterNode(new IdentifierExpression{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText(), {}}));
|
||||
}
|
||||
std::vector<TypeExpression*> templateArguments;
|
||||
if (context->genericSpecializationTypeList()) {
|
||||
templateArguments =
|
||||
GetTypeVector(context->genericSpecializationTypeList()->typeList());
|
||||
|
||||
if (auto* e = context->expression()) {
|
||||
return implicit_cast<Expression*>(RegisterNode(new ElementAccessExpression{
|
||||
Pos(context), location, e->accept(this).as<Expression*>()}));
|
||||
}
|
||||
return implicit_cast<Expression*>(RegisterNode(new IdentifierExpression{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
|
||||
std::move(templateArguments)}));
|
||||
|
||||
return implicit_cast<Expression*>(RegisterNode(new FieldAccessExpression{
|
||||
Pos(context), location, context->IDENTIFIER()->getSymbol()->getText()}));
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitUnaryExpression(
|
||||
@ -768,6 +795,22 @@ antlrcpp::Any AstGenerator::visitDiagnosticStatement(
|
||||
}
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* context) {
|
||||
StructDeclaration* struct_declaration = RegisterNode(new StructDeclaration{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText()});
|
||||
|
||||
for (auto* fieldDeclaration :
|
||||
context->fieldListDeclaration()->fieldDeclaration()) {
|
||||
FieldNameAndType field = {
|
||||
fieldDeclaration->IDENTIFIER()->getSymbol()->getText(),
|
||||
GetType(fieldDeclaration->type())};
|
||||
struct_declaration->fields.push_back(field);
|
||||
}
|
||||
|
||||
return implicit_cast<Declaration*>(struct_declaration);
|
||||
}
|
||||
|
||||
void AstGenerator::visitSourceFile(SourceFileContext* context) {
|
||||
source_file_context_ = context;
|
||||
current_source_file_ = SourceFileMap::Get().AddSource(context->name);
|
||||
|
@ -69,6 +69,9 @@ class AstGenerator : public TorqueBaseVisitor {
|
||||
antlrcpp::Any visitHelperCallStatement(
|
||||
TorqueParser::HelperCallStatementContext* context) override;
|
||||
|
||||
antlrcpp::Any visitStructExpression(
|
||||
TorqueParser::StructExpressionContext* context) override;
|
||||
|
||||
antlrcpp::Any visitConditionalExpression(
|
||||
TorqueParser::ConditionalExpressionContext* context) override;
|
||||
|
||||
@ -108,6 +111,9 @@ class AstGenerator : public TorqueBaseVisitor {
|
||||
antlrcpp::Any visitAssignment(
|
||||
TorqueParser::AssignmentContext* context) override;
|
||||
|
||||
antlrcpp::Any visitFunctionPointerExpression(
|
||||
TorqueParser::FunctionPointerExpressionContext* context) override;
|
||||
|
||||
antlrcpp::Any visitPrimaryExpression(
|
||||
TorqueParser::PrimaryExpressionContext* context) override;
|
||||
|
||||
@ -146,6 +152,9 @@ class AstGenerator : public TorqueBaseVisitor {
|
||||
antlrcpp::Any visitDiagnosticStatement(
|
||||
TorqueParser::DiagnosticStatementContext* context) override;
|
||||
|
||||
antlrcpp::Any visitStructDeclaration(
|
||||
TorqueParser::StructDeclarationContext* context) override;
|
||||
|
||||
antlrcpp::Any aggregateResult(antlrcpp::Any aggregate,
|
||||
const antlrcpp::Any& nextResult) override {
|
||||
if (aggregate.isNull())
|
||||
|
@ -29,6 +29,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition)
|
||||
|
||||
#define AST_EXPRESSION_NODE_KIND_LIST(V) \
|
||||
V(CallExpression) \
|
||||
V(StructExpression) \
|
||||
V(LogicalOrExpression) \
|
||||
V(LogicalAndExpression) \
|
||||
V(ConditionalExpression) \
|
||||
@ -69,6 +70,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition)
|
||||
V(GenericDeclaration) \
|
||||
V(SpecializationDeclaration) \
|
||||
V(ExternConstDeclaration) \
|
||||
V(StructDeclaration) \
|
||||
V(DefaultModuleDeclaration) \
|
||||
V(ExplicitModuleDeclaration) \
|
||||
V(ConstDeclaration)
|
||||
@ -260,6 +262,14 @@ struct CallExpression : Expression {
|
||||
std::vector<std::string> labels;
|
||||
};
|
||||
|
||||
struct StructExpression : Expression {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(StructExpression)
|
||||
StructExpression(SourcePosition p, std::string n, std::vector<Expression*> e)
|
||||
: Expression(kKind, p), name(n), expressions(std::move(e)) {}
|
||||
std::string name;
|
||||
std::vector<Expression*> expressions;
|
||||
};
|
||||
|
||||
struct LogicalOrExpression : Expression {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalOrExpression)
|
||||
LogicalOrExpression(SourcePosition p, Expression* l, Expression* r)
|
||||
@ -552,6 +562,11 @@ struct TypeAliasDeclaration : Declaration {
|
||||
TypeExpression* type;
|
||||
};
|
||||
|
||||
struct FieldNameAndType {
|
||||
std::string name;
|
||||
TypeExpression* type;
|
||||
};
|
||||
|
||||
struct LabelAndTypes {
|
||||
std::string name;
|
||||
std::vector<TypeExpression*> types;
|
||||
@ -693,6 +708,14 @@ struct ExternConstDeclaration : Declaration {
|
||||
std::string literal;
|
||||
};
|
||||
|
||||
struct StructDeclaration : Declaration {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration)
|
||||
StructDeclaration(SourcePosition p, std::string n)
|
||||
: Declaration(kKind, p), name(std::move(n)) {}
|
||||
std::string name;
|
||||
std::vector<FieldNameAndType> fields;
|
||||
};
|
||||
|
||||
#define ENUM_ITEM(name) \
|
||||
case AstNode::Kind::k##name: \
|
||||
return std::is_base_of<T, name>::value; \
|
||||
|
@ -34,6 +34,18 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
|
||||
return os;
|
||||
}
|
||||
|
||||
std::string Variable::RValue() const {
|
||||
if (!IsDefined()) {
|
||||
ReportError("Reading uninitialized variable.");
|
||||
}
|
||||
if (type()->IsStructType()) {
|
||||
return value();
|
||||
}
|
||||
std::string result = "(*" + value() + ")";
|
||||
if (!IsConst()) result += ".value()";
|
||||
return result;
|
||||
}
|
||||
|
||||
void PrintLabel(std::ostream& os, const Label& l, bool with_names) {
|
||||
os << l.name();
|
||||
if (l.GetParameterCount() != 0) {
|
||||
|
@ -134,14 +134,7 @@ class Variable : public Value {
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Variable, variable);
|
||||
bool IsConst() const override { return const_; }
|
||||
std::string value() const override { return value_; }
|
||||
std::string RValue() const override {
|
||||
if (!IsDefined()) {
|
||||
ReportError("Reading uninitialized variable.");
|
||||
}
|
||||
std::string result = "(*" + value() + ")";
|
||||
if (!IsConst()) result += ".value()";
|
||||
return result;
|
||||
}
|
||||
std::string RValue() const override;
|
||||
void Define() {
|
||||
if (defined_ && IsConst()) {
|
||||
ReportError("Cannot re-define a const-bound variable.");
|
||||
|
@ -95,6 +95,15 @@ Builtin* DeclarationVisitor::BuiltinDeclarationCommon(
|
||||
}
|
||||
}
|
||||
|
||||
if (const StructType* struct_type =
|
||||
StructType::DynamicCast(signature.return_type)) {
|
||||
std::stringstream stream;
|
||||
stream << "builtins (in this case" << decl->name
|
||||
<< ") cannot return structs (in this case " << struct_type->name()
|
||||
<< ")";
|
||||
ReportError(stream.str());
|
||||
}
|
||||
|
||||
std::string generated_name = GetGeneratedCallableName(
|
||||
decl->name, declarations()->GetCurrentSpecializationTypeNamesVector());
|
||||
return declarations()->DeclareBuiltin(generated_name, kind, external,
|
||||
@ -117,6 +126,15 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
|
||||
ReportError(stream.str());
|
||||
}
|
||||
|
||||
if (signature.return_type->IsStructType()) {
|
||||
std::stringstream stream;
|
||||
stream << "runtime functions (in this case" << decl->name
|
||||
<< ") cannot return structs (in this case "
|
||||
<< static_cast<const StructType*>(signature.return_type)->name()
|
||||
<< ")";
|
||||
ReportError(stream.str());
|
||||
}
|
||||
|
||||
declarations()->DeclareRuntimeFunction(decl->name, signature);
|
||||
}
|
||||
|
||||
@ -158,9 +176,9 @@ void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
|
||||
DeclareSignature(signature);
|
||||
Variable* return_variable = nullptr;
|
||||
if (!signature.return_type->IsVoidOrNever()) {
|
||||
return_variable = declarations()->DeclareVariable(
|
||||
kReturnValueVariable, signature.return_type,
|
||||
signature.return_type->IsConstexpr());
|
||||
return_variable =
|
||||
DeclareVariable(kReturnValueVariable, signature.return_type,
|
||||
signature.return_type->IsConstexpr());
|
||||
}
|
||||
|
||||
PushControlSplit();
|
||||
@ -252,6 +270,33 @@ void DeclarationVisitor::Visit(ReturnStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
Variable* DeclarationVisitor::DeclareVariable(const std::string& name,
|
||||
const Type* type, bool is_const) {
|
||||
Variable* result = declarations()->DeclareVariable(name, type, is_const);
|
||||
if (type->IsStructType()) {
|
||||
const StructType* struct_type = StructType::cast(type);
|
||||
for (auto& field : struct_type->fields()) {
|
||||
std::string field_var_name = name + "." + field.name;
|
||||
DeclareVariable(field_var_name, field.type, is_const);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Parameter* DeclarationVisitor::DeclareParameter(const std::string& name,
|
||||
const Type* type) {
|
||||
Parameter* result = declarations()->DeclareParameter(
|
||||
name, GetParameterVariableFromName(name), type);
|
||||
if (type->IsStructType()) {
|
||||
const StructType* struct_type = StructType::cast(type);
|
||||
for (auto& field : struct_type->fields()) {
|
||||
std::string field_var_name = name + "." + field.name;
|
||||
DeclareParameter(field_var_name, field.type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) {
|
||||
std::string variable_name = stmt->name;
|
||||
const Type* type = declarations()->GetType(stmt->type);
|
||||
@ -259,7 +304,7 @@ void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) {
|
||||
ReportError(
|
||||
"cannot declare variable with constexpr type. Use 'const' instead.");
|
||||
}
|
||||
declarations()->DeclareVariable(variable_name, type, stmt->const_qualified);
|
||||
DeclareVariable(variable_name, type, stmt->const_qualified);
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared variable " << variable_name << " with type " << *type
|
||||
<< "\n";
|
||||
@ -293,6 +338,15 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
|
||||
declarations()->DeclareExternConstant(decl->name, type, decl->literal);
|
||||
}
|
||||
|
||||
void DeclarationVisitor::Visit(StructDeclaration* decl) {
|
||||
std::vector<NameAndType> fields;
|
||||
for (auto& field : decl->fields) {
|
||||
const Type* field_type = declarations()->GetType(field.type);
|
||||
fields.push_back({field.name, field_type});
|
||||
}
|
||||
declarations()->DeclareStruct(CurrentModule(), decl->name, fields);
|
||||
}
|
||||
|
||||
void DeclarationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
{
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||
@ -415,8 +469,7 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) {
|
||||
ReportError("no constexpr type allowed for label arguments");
|
||||
}
|
||||
|
||||
shared_label->AddVariable(
|
||||
declarations()->DeclareVariable(p, type, false));
|
||||
shared_label->AddVariable(DeclareVariable(p, type, false));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@ -556,8 +609,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) {
|
||||
for (auto name : signature.parameter_names) {
|
||||
const Type* t(*type_iterator++);
|
||||
if (name.size() != 0) {
|
||||
declarations()->DeclareParameter(name, GetParameterVariableFromName(name),
|
||||
t);
|
||||
DeclareParameter(name, t);
|
||||
}
|
||||
}
|
||||
for (auto& label : signature.labels) {
|
||||
@ -570,8 +622,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) {
|
||||
}
|
||||
|
||||
std::string var_name = label.name + std::to_string(i++);
|
||||
new_label->AddVariable(
|
||||
declarations()->DeclareVariable(var_name, var_type, false));
|
||||
new_label->AddVariable(DeclareVariable(var_name, var_type, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,10 @@ class DeclarationVisitor : public FileVisitor {
|
||||
|
||||
void Visit(VarDeclarationStatement* stmt);
|
||||
void Visit(ExternConstDeclaration* decl);
|
||||
|
||||
void Visit(StructDeclaration* decl);
|
||||
void Visit(StructExpression* decl) {}
|
||||
|
||||
void Visit(LogicalOrExpression* expr);
|
||||
void Visit(LogicalAndExpression* expr);
|
||||
void DeclareExpressionForBranch(Expression* node);
|
||||
@ -148,6 +152,10 @@ class DeclarationVisitor : public FileVisitor {
|
||||
live_and_changed_variables_.push_back(live_and_changed);
|
||||
}
|
||||
|
||||
Variable* DeclareVariable(const std::string& name, const Type* type,
|
||||
bool is_const);
|
||||
Parameter* DeclareParameter(const std::string& name, const Type* type);
|
||||
|
||||
std::set<const Variable*> PopControlSplit() {
|
||||
auto result = live_and_changed_variables_.back().changed;
|
||||
live_and_changed_variables_.pop_back();
|
||||
|
@ -224,6 +224,12 @@ void Declarations::DeclareType(const std::string& name, const Type* type) {
|
||||
Declare(name, std::unique_ptr<TypeAlias>(result));
|
||||
}
|
||||
|
||||
void Declarations::DeclareStruct(Module* module, const std::string& name,
|
||||
const std::vector<NameAndType>& fields) {
|
||||
const StructType* new_type = TypeOracle::GetStructType(module, name, fields);
|
||||
DeclareType(name, new_type);
|
||||
}
|
||||
|
||||
Label* Declarations::DeclareLabel(const std::string& name) {
|
||||
CheckAlreadyDeclared(name, "label");
|
||||
Label* result = new Label(name);
|
||||
@ -289,7 +295,9 @@ RuntimeFunction* Declarations::DeclareRuntimeFunction(
|
||||
|
||||
Variable* Declarations::DeclareVariable(const std::string& var,
|
||||
const Type* type, bool is_const) {
|
||||
std::string name(var + std::to_string(GetNextUniqueDeclarationNumber()));
|
||||
std::string name(var + "_" +
|
||||
std::to_string(GetNextUniqueDeclarationNumber()));
|
||||
std::replace(name.begin(), name.end(), '.', '_');
|
||||
CheckAlreadyDeclared(var, "variable");
|
||||
Variable* result = new Variable(var, name, type, is_const);
|
||||
Declare(var, std::unique_ptr<Declarable>(result));
|
||||
|
@ -76,6 +76,9 @@ class Declarations {
|
||||
|
||||
void DeclareType(const std::string& name, const Type* type);
|
||||
|
||||
void DeclareStruct(Module* module, const std::string& name,
|
||||
const std::vector<NameAndType>& fields);
|
||||
|
||||
Label* DeclareLabel(const std::string& name);
|
||||
|
||||
Macro* DeclareMacro(const std::string& name, const Signature& signature,
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/torque/implementation-visitor.h"
|
||||
#include "src/torque/parameter-difference.h"
|
||||
|
||||
@ -188,6 +190,18 @@ void ImplementationVisitor::Visit(ConstDeclaration* decl) {
|
||||
source_out() << "}\n\n";
|
||||
}
|
||||
|
||||
void ImplementationVisitor::Visit(StructDeclaration* decl) {
|
||||
header_out() << " struct " << decl->name << " {\n";
|
||||
const StructType* struct_type =
|
||||
static_cast<const StructType*>(declarations()->LookupType(decl->name));
|
||||
for (auto& field : struct_type->fields()) {
|
||||
header_out() << " " << field.type->GetGeneratedTypeName();
|
||||
header_out() << " " << field.name << ";\n";
|
||||
}
|
||||
header_out() << " } "
|
||||
<< ";\n";
|
||||
}
|
||||
|
||||
void ImplementationVisitor::Visit(TorqueMacroDeclaration* decl,
|
||||
const Signature& sig, Statement* body) {
|
||||
Signature signature = MakeSignature(decl->signature.get());
|
||||
@ -246,7 +260,8 @@ void ImplementationVisitor::Visit(TorqueMacroDeclaration* decl,
|
||||
if (result_var != nullptr) {
|
||||
GenerateIndent();
|
||||
source_out() << "return "
|
||||
<< VisitResult(result_var->type(), result_var).RValue()
|
||||
<< RValueFlattenStructs(
|
||||
VisitResult(result_var->type(), result_var))
|
||||
<< ";" << std::endl;
|
||||
}
|
||||
source_out() << "}" << std::endl << std::endl;
|
||||
@ -335,7 +350,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
source_out() << "" << std::endl;
|
||||
left = Visit(expr->if_true);
|
||||
GenerateIndent();
|
||||
source_out() << "return " << left.RValue() << ";" << std::endl;
|
||||
source_out() << "return " << RValueFlattenStructs(left) << ";" << std::endl;
|
||||
}
|
||||
source_out() << ";" << std::endl;
|
||||
GenerateIndent();
|
||||
@ -345,7 +360,8 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
source_out() << "" << std::endl;
|
||||
right = Visit(expr->if_false);
|
||||
GenerateIndent();
|
||||
source_out() << "return " << right.RValue() << ";" << std::endl;
|
||||
source_out() << "return " << RValueFlattenStructs(right) << ";"
|
||||
<< std::endl;
|
||||
}
|
||||
source_out() << ";" << std::endl;
|
||||
|
||||
@ -397,7 +413,7 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
if (left_result.type()->IsBool()) {
|
||||
Label* true_label = declarations()->LookupLabel(kTrueLabelName);
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIf(" << left_result.RValue() << ", "
|
||||
source_out() << "GotoIf(" << RValueFlattenStructs(left_result) << ", "
|
||||
<< true_label->generated() << ");" << std::endl;
|
||||
} else if (!left_result.type()->IsConstexprBool()) {
|
||||
GenerateLabelBind(false_label);
|
||||
@ -412,9 +428,9 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
ReportError(stream.str());
|
||||
}
|
||||
if (left_result.type()->IsConstexprBool()) {
|
||||
return VisitResult(left_result.type(), std::string("(") +
|
||||
left_result.RValue() + " || " +
|
||||
right_result.RValue() + ")");
|
||||
return VisitResult(left_result.type(),
|
||||
std::string("(") + RValueFlattenStructs(left_result) +
|
||||
" || " + RValueFlattenStructs(right_result) + ")");
|
||||
} else {
|
||||
return right_result;
|
||||
}
|
||||
@ -430,7 +446,7 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||
if (left_result.type()->IsBool()) {
|
||||
Label* false_label = declarations()->LookupLabel(kFalseLabelName);
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIfNot(" << left_result.RValue() << ", "
|
||||
source_out() << "GotoIfNot(" << RValueFlattenStructs(left_result) << ", "
|
||||
<< false_label->generated() << ");" << std::endl;
|
||||
} else if (!left_result.type()->IsConstexprBool()) {
|
||||
GenerateLabelBind(true_label);
|
||||
@ -445,9 +461,9 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||
ReportError(stream.str());
|
||||
}
|
||||
if (left_result.type()->IsConstexprBool()) {
|
||||
return VisitResult(left_result.type(), std::string("(") +
|
||||
left_result.RValue() + " && " +
|
||||
right_result.RValue() + ")");
|
||||
return VisitResult(left_result.type(),
|
||||
std::string("(") + RValueFlattenStructs(left_result) +
|
||||
" && " + RValueFlattenStructs(right_result) + ")");
|
||||
} else {
|
||||
return right_result;
|
||||
}
|
||||
@ -591,7 +607,8 @@ const Type* ImplementationVisitor::Visit(IfStatement* stmt) {
|
||||
const Type* right_result = TypeOracle::GetVoidType();
|
||||
{
|
||||
GenerateIndent();
|
||||
source_out() << "if ((" << expression_result.RValue() << ")) ";
|
||||
source_out() << "if ((" << RValueFlattenStructs(expression_result)
|
||||
<< ")) ";
|
||||
ScopedIndent indent(this, false);
|
||||
source_out() << std::endl;
|
||||
left_result = Visit(stmt->if_true);
|
||||
@ -807,11 +824,12 @@ const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
|
||||
} else if (current_callable->IsBuiltin()) {
|
||||
if (Builtin::cast(current_callable)->IsVarArgsJavaScript()) {
|
||||
GenerateIndent();
|
||||
source_out() << "arguments->PopAndReturn(" << return_result.RValue()
|
||||
<< ");" << std::endl;
|
||||
source_out() << "arguments->PopAndReturn("
|
||||
<< RValueFlattenStructs(return_result) << ");"
|
||||
<< std::endl;
|
||||
} else {
|
||||
GenerateIndent();
|
||||
source_out() << "Return(" << return_result.RValue() << ");"
|
||||
source_out() << "Return(" << RValueFlattenStructs(return_result) << ");"
|
||||
<< std::endl;
|
||||
}
|
||||
} else {
|
||||
@ -1070,8 +1088,11 @@ void ImplementationVisitor::GenerateFunctionDeclaration(
|
||||
// Quite a hack here. Make sure that TNode is namespace qualified if the
|
||||
// macro/constant name is also qualified.
|
||||
std::string return_type_name(signature.return_type->GetGeneratedTypeName());
|
||||
if (macro_prefix != "" && (return_type_name.length() > 5) &&
|
||||
(return_type_name.substr(0, 5) == "TNode")) {
|
||||
if (const StructType* struct_type =
|
||||
StructType::DynamicCast(signature.return_type)) {
|
||||
o << GetDSLAssemblerName(struct_type->module()) << "::";
|
||||
} else if (macro_prefix != "" && (return_type_name.length() > 5) &&
|
||||
(return_type_name.substr(0, 5) == "TNode")) {
|
||||
o << "compiler::";
|
||||
}
|
||||
o << return_type_name;
|
||||
@ -1220,21 +1241,33 @@ Callable* ImplementationVisitor::LookupCall(const std::string& name,
|
||||
return result;
|
||||
}
|
||||
|
||||
void ImplementationVisitor::GetFlattenedStructsVars(
|
||||
const Variable* base, std::set<const Variable*>& vars) {
|
||||
const Type* type = base->type();
|
||||
if (base->IsConst()) return;
|
||||
if (type->IsStructType()) {
|
||||
const StructType* struct_type = StructType::cast(type);
|
||||
for (auto& field : struct_type->fields()) {
|
||||
std::string field_var_name = base->name() + "." + field.name;
|
||||
GetFlattenedStructsVars(
|
||||
Variable::cast(declarations()->LookupValue(field_var_name)), vars);
|
||||
}
|
||||
} else {
|
||||
vars.insert(base);
|
||||
}
|
||||
}
|
||||
|
||||
void ImplementationVisitor::GenerateChangedVarsFromControlSplit(AstNode* node) {
|
||||
const std::set<const Variable*>& changed_vars =
|
||||
global_context_.GetControlSplitChangedVariables(
|
||||
node, declarations()->GetCurrentSpecializationTypeNamesVector());
|
||||
source_out() << "{";
|
||||
bool first = true;
|
||||
std::set<const Variable*> flattened_vars;
|
||||
for (auto v : changed_vars) {
|
||||
if (v->IsConst()) continue;
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
source_out() << ", ";
|
||||
}
|
||||
source_out() << v->value();
|
||||
GetFlattenedStructsVars(v, flattened_vars);
|
||||
}
|
||||
source_out() << "{";
|
||||
PrintCommaSeparatedList(source_out(), flattened_vars,
|
||||
[&](const Variable* v) { return v->value(); });
|
||||
source_out() << "}";
|
||||
}
|
||||
|
||||
@ -1254,12 +1287,42 @@ const Type* ImplementationVisitor::GetCommonType(const Type* left,
|
||||
|
||||
VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) {
|
||||
std::string temp = GenerateNewTempVariable(to_copy.type());
|
||||
source_out() << to_copy.RValue() << ";" << std::endl;
|
||||
source_out() << RValueFlattenStructs(to_copy) << ";" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << temp << ");" << std::endl;
|
||||
return VisitResult(to_copy.type(), temp);
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(StructExpression* decl) {
|
||||
const Type* raw_type = declarations()->LookupType(decl->name);
|
||||
if (!raw_type->IsStructType()) {
|
||||
std::stringstream s;
|
||||
s << decl->name << " is not a struct but used like one ";
|
||||
ReportError(s.str());
|
||||
}
|
||||
const StructType* struct_type = StructType::cast(raw_type);
|
||||
if (struct_type->fields().size() != decl->expressions.size()) {
|
||||
std::stringstream s;
|
||||
s << "initializer count mismatch for struct " << decl->name << " (expected "
|
||||
<< struct_type->fields().size() << ", found " << decl->expressions.size()
|
||||
<< ")";
|
||||
ReportError(s.str());
|
||||
}
|
||||
std::vector<VisitResult> expression_results;
|
||||
for (auto& field : struct_type->fields()) {
|
||||
VisitResult value = Visit(decl->expressions[expression_results.size()]);
|
||||
value = GenerateImplicitConvert(field.type, value);
|
||||
expression_results.push_back(value);
|
||||
}
|
||||
std::string result_var_name = GenerateNewTempVariable(struct_type);
|
||||
source_out() << "{";
|
||||
PrintCommaSeparatedList(
|
||||
source_out(), expression_results,
|
||||
[&](const VisitResult& result) { return RValueFlattenStructs(result); });
|
||||
source_out() << "};\n";
|
||||
return VisitResult(struct_type, result_var_name);
|
||||
}
|
||||
|
||||
LocationReference ImplementationVisitor::GetLocationReference(
|
||||
LocationExpression* location) {
|
||||
switch (location->kind) {
|
||||
@ -1276,6 +1339,47 @@ LocationReference ImplementationVisitor::GetLocationReference(
|
||||
}
|
||||
}
|
||||
|
||||
LocationReference ImplementationVisitor::GetLocationReference(
|
||||
FieldAccessExpression* expr) {
|
||||
VisitResult result = Visit(expr->object);
|
||||
if (result.type()->IsStructType()) {
|
||||
if (result.declarable()) {
|
||||
return LocationReference(
|
||||
declarations()->LookupValue((*result.declarable())->name() + "." +
|
||||
expr->field),
|
||||
{}, {});
|
||||
|
||||
} else {
|
||||
return LocationReference(
|
||||
nullptr,
|
||||
VisitResult(result.type(), result.RValue() + "." + expr->field), {});
|
||||
}
|
||||
}
|
||||
return LocationReference(nullptr, result, {});
|
||||
}
|
||||
|
||||
std::string ImplementationVisitor::RValueFlattenStructs(VisitResult result) {
|
||||
if (result.declarable()) {
|
||||
const Value* value = *result.declarable();
|
||||
const Type* type = value->type();
|
||||
if (const StructType* struct_type = StructType::DynamicCast(type)) {
|
||||
std::stringstream s;
|
||||
s << struct_type->name() << "{";
|
||||
PrintCommaSeparatedList(
|
||||
s, struct_type->fields(), [&](const NameAndType& field) {
|
||||
std::string field_declaration = value->name() + "." + field.name;
|
||||
Variable* field_variable =
|
||||
Variable::cast(declarations()->LookupValue(field_declaration));
|
||||
return RValueFlattenStructs(
|
||||
VisitResult(field_variable->type(), field_variable));
|
||||
});
|
||||
s << "}";
|
||||
return s.str();
|
||||
}
|
||||
}
|
||||
return result.RValue();
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::GenerateFetchFromLocation(
|
||||
LocationExpression* location, LocationReference reference) {
|
||||
switch (location->kind) {
|
||||
@ -1293,28 +1397,77 @@ VisitResult ImplementationVisitor::GenerateFetchFromLocation(
|
||||
}
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::GenerateFetchFromLocation(
|
||||
FieldAccessExpression* expr, LocationReference reference) {
|
||||
const Type* type = reference.base.type();
|
||||
if (reference.value != nullptr) {
|
||||
return GenerateFetchFromLocation(reference);
|
||||
} else if (const StructType* struct_type = StructType::DynamicCast(type)) {
|
||||
auto& fields = struct_type->fields();
|
||||
auto i = std::find_if(
|
||||
fields.begin(), fields.end(),
|
||||
[&](const NameAndType& f) { return f.name == expr->field; });
|
||||
if (i == fields.end()) {
|
||||
std::stringstream s;
|
||||
s << "\"" << expr->field << "\" is not a field of struct type \""
|
||||
<< struct_type->name() << "\"";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return VisitResult(i->type, reference.base.RValue());
|
||||
} else {
|
||||
Arguments arguments;
|
||||
arguments.parameters = {reference.base};
|
||||
return GenerateCall(std::string(".") + expr->field, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
void ImplementationVisitor::GenerateAssignToVariable(Variable* var,
|
||||
VisitResult value) {
|
||||
VisitResult casted_value = GenerateImplicitConvert(var->type(), value);
|
||||
GenerateIndent();
|
||||
VisitResult variable_result = {var->type(), var};
|
||||
source_out() << variable_result.LValue() << " = " << casted_value.RValue()
|
||||
<< ";\n";
|
||||
if (var->type()->IsStructType()) {
|
||||
if (value.type() != var->type()) {
|
||||
std::stringstream s;
|
||||
s << "incompatable assignment from type " << *value.type() << " to "
|
||||
<< *var->type();
|
||||
ReportError(s.str());
|
||||
}
|
||||
const StructType* struct_type = StructType::cast(var->type());
|
||||
for (auto& field : struct_type->fields()) {
|
||||
std::string field_declaration = var->name() + "." + field.name;
|
||||
Variable* field_variable =
|
||||
Variable::cast(declarations()->LookupValue(field_declaration));
|
||||
if (value.declarable() && (*value.declarable())->IsVariable()) {
|
||||
Variable* source_field = Variable::cast(declarations()->LookupValue(
|
||||
Variable::cast((*value.declarable()))->name() + "." + field.name));
|
||||
GenerateAssignToVariable(
|
||||
field_variable, VisitResult{source_field->type(), source_field});
|
||||
} else {
|
||||
GenerateAssignToVariable(
|
||||
field_variable, VisitResult{field_variable->type(),
|
||||
value.RValue() + "." + field.name});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VisitResult casted_value = GenerateImplicitConvert(var->type(), value);
|
||||
GenerateIndent();
|
||||
VisitResult var_value = {var->type(), var};
|
||||
source_out() << var_value.LValue() << " = "
|
||||
<< RValueFlattenStructs(casted_value) << ";" << std::endl;
|
||||
}
|
||||
var->Define();
|
||||
}
|
||||
|
||||
void ImplementationVisitor::GenerateAssignToLocation(
|
||||
LocationExpression* location, const LocationReference& reference,
|
||||
VisitResult assignment_value) {
|
||||
if (IdentifierExpression::cast(location)) {
|
||||
if (reference.value != nullptr) {
|
||||
Value* value = reference.value;
|
||||
if (value->IsConst()) {
|
||||
Variable* var = Variable::cast(value);
|
||||
if (var->IsConst()) {
|
||||
std::stringstream s;
|
||||
s << "\"" << value->name()
|
||||
s << "\"" << var->name()
|
||||
<< "\" is declared const (maybe implicitly) and cannot be assigned to";
|
||||
ReportError(s.str());
|
||||
}
|
||||
Variable* var = Variable::cast(value);
|
||||
GenerateAssignToVariable(var, assignment_value);
|
||||
} else if (auto access = FieldAccessExpression::cast(location)) {
|
||||
GenerateCall(std::string(".") + access->field + "=",
|
||||
@ -1326,6 +1479,36 @@ void ImplementationVisitor::GenerateAssignToLocation(
|
||||
}
|
||||
}
|
||||
|
||||
void ImplementationVisitor::GenerateVariableDeclaration(const Variable* var) {
|
||||
const Type* var_type = var->type();
|
||||
if (var_type->IsStructType()) {
|
||||
const StructType* struct_type = StructType::cast(var_type);
|
||||
for (auto& field : struct_type->fields()) {
|
||||
GenerateVariableDeclaration(Variable::cast(
|
||||
declarations()->LookupValue(var->name() + "." + field.name)));
|
||||
}
|
||||
} else {
|
||||
std::string value = var->value();
|
||||
GenerateIndent();
|
||||
if (var_type->IsConstexpr()) {
|
||||
source_out() << var_type->GetGeneratedTypeName();
|
||||
source_out() << " " << value << "_impl;" << std::endl;
|
||||
} else if (var->IsConst()) {
|
||||
source_out() << "TNode<" << var->type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << "> " << var->value() << "_impl;\n";
|
||||
} else {
|
||||
source_out() << "TVARIABLE(";
|
||||
source_out() << var_type->GetGeneratedTNodeTypeName();
|
||||
source_out() << ", " << value << "_impl);" << std::endl;
|
||||
}
|
||||
GenerateIndent();
|
||||
source_out() << "auto " << value << " = &" << value << "_impl;"
|
||||
<< std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << value << ");" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
AstNode* node, const std::string& name,
|
||||
const base::Optional<const Type*>& type,
|
||||
@ -1344,24 +1527,7 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
node, declarations()->GetCurrentSpecializationTypeNamesVector(),
|
||||
variable);
|
||||
}
|
||||
|
||||
GenerateIndent();
|
||||
if (variable->type()->IsConstexpr()) {
|
||||
source_out() << variable->type()->GetGeneratedTypeName();
|
||||
source_out() << " " << variable->value() << "_impl;\n";
|
||||
} else if (variable->IsConst()) {
|
||||
source_out() << "TNode<" << variable->type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << "> " << variable->value() << "_impl;\n";
|
||||
} else {
|
||||
source_out() << "TVARIABLE(";
|
||||
source_out() << variable->type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << ", " << variable->value() << "_impl);\n";
|
||||
}
|
||||
GenerateIndent();
|
||||
source_out() << "auto " << variable->value() << " = &" << variable->value()
|
||||
<< "_impl;\n";
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << variable->value() << ");\n";
|
||||
GenerateVariableDeclaration(variable);
|
||||
if (initialization) {
|
||||
GenerateAssignToVariable(variable, *initialization);
|
||||
}
|
||||
@ -1431,7 +1597,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
|
||||
const Type* to_type = type->parameter_types()[current];
|
||||
VisitResult result =
|
||||
GenerateImplicitConvert(to_type, arguments.parameters[current]);
|
||||
variables.push_back(result.RValue());
|
||||
variables.push_back(RValueFlattenStructs(result));
|
||||
}
|
||||
|
||||
std::string result_variable_name;
|
||||
@ -1439,10 +1605,15 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
|
||||
if (no_result) {
|
||||
GenerateIndent();
|
||||
} else {
|
||||
result_variable_name = GenerateNewTempVariable(type->return_type());
|
||||
source_out() << "UncheckedCast<";
|
||||
source_out() << type->return_type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << ">(";
|
||||
const Type* return_type = type->return_type();
|
||||
result_variable_name = GenerateNewTempVariable(return_type);
|
||||
if (return_type->IsStructType()) {
|
||||
source_out() << "(";
|
||||
} else {
|
||||
source_out() << "UncheckedCast<";
|
||||
source_out() << type->return_type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << ">(";
|
||||
}
|
||||
}
|
||||
|
||||
Builtin* example_builtin =
|
||||
@ -1460,7 +1631,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
|
||||
}
|
||||
source_out() << "Builtins::CallableFor(isolate(), Builtins::k"
|
||||
<< example_builtin->name() << ").descriptor(), "
|
||||
<< callee_result.RValue() << ", ";
|
||||
<< RValueFlattenStructs(callee_result) << ", ";
|
||||
|
||||
size_t total_parameters = 0;
|
||||
for (size_t i = 0; i < arguments.parameters.size(); ++i) {
|
||||
@ -1499,7 +1670,7 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
: callable->signature().types()[current];
|
||||
VisitResult result =
|
||||
GenerateImplicitConvert(to_type, arguments.parameters[current]);
|
||||
variables.push_back(result.RValue());
|
||||
variables.push_back(RValueFlattenStructs(result));
|
||||
}
|
||||
|
||||
std::string result_variable_name;
|
||||
@ -1508,9 +1679,13 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
} else {
|
||||
result_variable_name = GenerateNewTempVariable(result_type);
|
||||
if (!result_type->IsConstexpr()) {
|
||||
source_out() << "UncheckedCast<";
|
||||
source_out() << result_type->GetGeneratedTNodeTypeName();
|
||||
source_out() << ">(";
|
||||
if (result_type->IsStructType()) {
|
||||
source_out() << "(";
|
||||
} else {
|
||||
source_out() << "UncheckedCast<";
|
||||
source_out() << result_type->GetGeneratedTNodeTypeName();
|
||||
source_out() << ">(";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callable->IsBuiltin()) {
|
||||
@ -1663,7 +1838,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
|
||||
}
|
||||
if (!result.type()->IsVoidOrNever()) {
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << result.RValue() << ");" << std::endl;
|
||||
source_out() << "USE(" << RValueFlattenStructs(result) << ");" << std::endl;
|
||||
}
|
||||
if (is_tailcall) {
|
||||
result = {TypeOracle::GetNeverType(), ""};
|
||||
@ -1695,7 +1870,7 @@ void ImplementationVisitor::GenerateBranch(const VisitResult& condition,
|
||||
Label* true_label,
|
||||
Label* false_label) {
|
||||
GenerateIndent();
|
||||
source_out() << "Branch(" << condition.RValue() << ", "
|
||||
source_out() << "Branch(" << RValueFlattenStructs(condition) << ", "
|
||||
<< true_label->generated() << ", " << false_label->generated()
|
||||
<< ");" << std::endl;
|
||||
}
|
||||
|
@ -37,35 +37,31 @@ class ImplementationVisitor : public FileVisitor {
|
||||
const Type* Visit(Statement* stmt);
|
||||
void Visit(Declaration* decl);
|
||||
|
||||
VisitResult Visit(StructExpression* decl);
|
||||
|
||||
LocationReference GetLocationReference(LocationExpression* location);
|
||||
LocationReference GetLocationReference(IdentifierExpression* expr) {
|
||||
return LocationReference(declarations()->LookupValue(expr->name), {}, {});
|
||||
}
|
||||
LocationReference GetLocationReference(FieldAccessExpression* expr) {
|
||||
return LocationReference({}, Visit(expr->object), {});
|
||||
}
|
||||
LocationReference GetLocationReference(FieldAccessExpression* expr);
|
||||
LocationReference GetLocationReference(ElementAccessExpression* expr) {
|
||||
return LocationReference({}, Visit(expr->array), Visit(expr->index));
|
||||
}
|
||||
|
||||
std::string RValueFlattenStructs(VisitResult result);
|
||||
|
||||
VisitResult GenerateFetchFromLocation(LocationReference reference) {
|
||||
const Value* value = reference.value;
|
||||
return VisitResult(value->type(), value);
|
||||
}
|
||||
VisitResult GenerateFetchFromLocation(LocationExpression* location,
|
||||
LocationReference reference);
|
||||
VisitResult GenerateFetchFromLocation(IdentifierExpression* expr,
|
||||
LocationReference reference) {
|
||||
Value* value = reference.value;
|
||||
if (value->IsVariable() && !Variable::cast(value)->IsDefined()) {
|
||||
std::stringstream s;
|
||||
s << "\"" << value->name() << "\" is used before it is defined";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return VisitResult(value->type(), value);
|
||||
return GenerateFetchFromLocation(reference);
|
||||
}
|
||||
VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr,
|
||||
LocationReference reference) {
|
||||
Arguments arguments;
|
||||
arguments.parameters = {reference.base};
|
||||
return GenerateCall(std::string(".") + expr->field, arguments);
|
||||
}
|
||||
LocationReference reference);
|
||||
VisitResult GenerateFetchFromLocation(ElementAccessExpression* expr,
|
||||
LocationReference reference) {
|
||||
Arguments arguments;
|
||||
@ -93,6 +89,7 @@ class ImplementationVisitor : public FileVisitor {
|
||||
void Visit(TypeDeclaration* decl) {}
|
||||
void Visit(TypeAliasDeclaration* decl) {}
|
||||
void Visit(ExternConstDeclaration* decl) {}
|
||||
void Visit(StructDeclaration* decl);
|
||||
void Visit(StandardDeclaration* decl);
|
||||
void Visit(GenericDeclaration* decl) {}
|
||||
void Visit(SpecializationDeclaration* decl);
|
||||
@ -176,6 +173,11 @@ class ImplementationVisitor : public FileVisitor {
|
||||
|
||||
Callable* LookupCall(const std::string& name, const Arguments& arguments);
|
||||
|
||||
bool GenerateChangedVarFromControlSplit(const Variable* v, bool first = true);
|
||||
|
||||
void GetFlattenedStructsVars(const Variable* base,
|
||||
std::set<const Variable*>& vars);
|
||||
|
||||
void GenerateChangedVarsFromControlSplit(AstNode* node);
|
||||
|
||||
const Type* GetCommonType(const Type* left, const Type* right);
|
||||
@ -188,6 +190,8 @@ class ImplementationVisitor : public FileVisitor {
|
||||
const LocationReference& reference,
|
||||
VisitResult assignment_value);
|
||||
|
||||
void GenerateVariableDeclaration(const Variable* var);
|
||||
|
||||
Variable* GenerateVariableDeclaration(
|
||||
AstNode* node, const std::string& name,
|
||||
const base::Optional<const Type*>& type,
|
||||
|
@ -29,6 +29,14 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
||||
return result;
|
||||
}
|
||||
|
||||
static const StructType* GetStructType(
|
||||
Module* module, const std::string& name,
|
||||
const std::vector<NameAndType>& fields) {
|
||||
StructType* result = new StructType(module, name, fields);
|
||||
Get().struct_types_.push_back(std::unique_ptr<StructType>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static const FunctionPointerType* GetFunctionPointerType(
|
||||
TypeVector argument_types, const Type* return_type) {
|
||||
const Type* code_type = Get().GetBuiltinType(CODE_TYPE_STRING);
|
||||
@ -101,6 +109,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
||||
Deduplicator<FunctionPointerType> function_pointer_types_;
|
||||
Deduplicator<UnionType> union_types_;
|
||||
std::vector<std::unique_ptr<Type>> nominal_types_;
|
||||
std::vector<std::unique_ptr<Type>> struct_types_;
|
||||
};
|
||||
|
||||
} // namespace torque
|
||||
|
@ -154,6 +154,14 @@ const Type* UnionType::NonConstexprVersion() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
std::string StructType::ToExplicitString() const {
|
||||
std::stringstream result;
|
||||
result << "{";
|
||||
PrintCommaSeparatedList(result, fields_);
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
|
||||
os << "(";
|
||||
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
|
||||
@ -181,6 +189,13 @@ void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type) {
|
||||
os << name_and_type.name;
|
||||
os << ": ";
|
||||
os << *name_and_type.type;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Signature& sig) {
|
||||
PrintSignature(os, sig, true);
|
||||
return os;
|
||||
@ -256,7 +271,17 @@ std::string VisitResult::LValue() const {
|
||||
}
|
||||
|
||||
std::string VisitResult::RValue() const {
|
||||
return declarable_ ? (*declarable_)->RValue() : value_;
|
||||
if (declarable()) {
|
||||
auto value = *declarable();
|
||||
if (value->IsVariable() && !Variable::cast(value)->IsDefined()) {
|
||||
std::stringstream s;
|
||||
s << "\"" << value->name() << "\" is used before it is defined";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return value->RValue();
|
||||
} else {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace torque
|
||||
|
@ -37,13 +37,19 @@ class Value;
|
||||
|
||||
class TypeBase {
|
||||
public:
|
||||
enum class Kind { kAbstractType, kFunctionPointerType, kUnionType };
|
||||
enum class Kind {
|
||||
kAbstractType,
|
||||
kFunctionPointerType,
|
||||
kUnionType,
|
||||
kStructType
|
||||
};
|
||||
virtual ~TypeBase() {}
|
||||
bool IsAbstractType() const { return kind() == Kind::kAbstractType; }
|
||||
bool IsFunctionPointerType() const {
|
||||
return kind() == Kind::kFunctionPointerType;
|
||||
}
|
||||
bool IsUnionType() const { return kind() == Kind::kUnionType; }
|
||||
bool IsStructType() const { return kind() == Kind::kStructType; }
|
||||
|
||||
protected:
|
||||
explicit TypeBase(Kind kind) : kind_(kind) {}
|
||||
@ -111,6 +117,13 @@ class Type : public TypeBase {
|
||||
|
||||
using TypeVector = std::vector<const Type*>;
|
||||
|
||||
struct NameAndType {
|
||||
std::string name;
|
||||
const Type* type;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type);
|
||||
|
||||
class AbstractType final : public Type {
|
||||
public:
|
||||
DECLARE_TYPE_BOILERPLATE(AbstractType);
|
||||
@ -285,6 +298,37 @@ class UnionType final : public Type {
|
||||
std::set<const Type*, TypeLess> types_;
|
||||
};
|
||||
|
||||
class StructType final : public Type {
|
||||
public:
|
||||
DECLARE_TYPE_BOILERPLATE(StructType);
|
||||
std::string ToExplicitString() const override;
|
||||
std::string MangledName() const override { return name_; }
|
||||
std::string GetGeneratedTypeName() const override { return GetStructName(); }
|
||||
std::string GetGeneratedTNodeTypeName() const override { UNREACHABLE(); }
|
||||
const Type* NonConstexprVersion() const override { return this; }
|
||||
|
||||
bool IsConstexpr() const override { return false; }
|
||||
|
||||
const std::vector<NameAndType>& fields() const { return fields_; }
|
||||
const std::string& name() const { return name_; }
|
||||
Module* module() const { return module_; }
|
||||
|
||||
private:
|
||||
friend class TypeOracle;
|
||||
StructType(Module* module, const std::string& name,
|
||||
const std::vector<NameAndType>& fields)
|
||||
: Type(Kind::kStructType, nullptr),
|
||||
module_(module),
|
||||
name_(name),
|
||||
fields_(fields) {}
|
||||
|
||||
const std::string& GetStructName() const { return name_; }
|
||||
|
||||
Module* module_;
|
||||
std::string name_;
|
||||
std::vector<NameAndType> fields_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Type& t) {
|
||||
os << t.ToString();
|
||||
return os;
|
||||
@ -325,11 +369,6 @@ class VisitResultVector : public std::vector<VisitResult> {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const TypeVector& types);
|
||||
|
||||
struct NameAndType {
|
||||
std::string name;
|
||||
const Type* type;
|
||||
};
|
||||
|
||||
typedef std::vector<NameAndType> NameAndTypeVector;
|
||||
|
||||
struct LabelDefinition {
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
module test {
|
||||
macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
|
||||
if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
|
||||
return true;
|
||||
}
|
||||
if constexpr((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
@ -82,7 +82,7 @@ module test {
|
||||
}
|
||||
}
|
||||
|
||||
builtin GenericBuiltinTest<T: type>(c: Context, param: T): Object {
|
||||
builtin GenericBuiltinTest<T : type>(c: Context, param: T): Object {
|
||||
return Null;
|
||||
}
|
||||
|
||||
@ -98,7 +98,8 @@ module test {
|
||||
}
|
||||
|
||||
macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 {
|
||||
if constexpr (flag) goto Label4;
|
||||
if
|
||||
constexpr(flag) goto Label4;
|
||||
else
|
||||
goto Label5;
|
||||
}
|
||||
@ -125,7 +126,7 @@ module test {
|
||||
return False;
|
||||
}
|
||||
|
||||
macro GenericMacroTest<T: type>(param: T): Object {
|
||||
macro GenericMacroTest<T : type>(param: T): Object {
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
@ -133,7 +134,7 @@ module test {
|
||||
return param2;
|
||||
}
|
||||
|
||||
macro GenericMacroTestWithLabels<T: type>(param: T): Object labels X {
|
||||
macro GenericMacroTestWithLabels<T : type>(param: T): Object labels X {
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
@ -158,29 +159,29 @@ module test {
|
||||
}
|
||||
}
|
||||
|
||||
builtin TestHelperPlus1(context : Context, x : Smi) : Smi {
|
||||
builtin TestHelperPlus1(context: Context, x: Smi): Smi {
|
||||
return x + 1;
|
||||
}
|
||||
builtin TestHelperPlus2(context : Context, x : Smi) : Smi {
|
||||
builtin TestHelperPlus2(context: Context, x: Smi): Smi {
|
||||
return x + 2;
|
||||
}
|
||||
|
||||
macro TestFunctionPointers(context : Context) : Boolean {
|
||||
let fptr : builtin(Context, Smi) => Smi = TestHelperPlus1;
|
||||
macro TestFunctionPointers(context: Context): Boolean {
|
||||
let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
|
||||
check(fptr(context, 42) == 43);
|
||||
fptr = TestHelperPlus2;
|
||||
check(fptr(context, 42) == 44);
|
||||
return True;
|
||||
}
|
||||
|
||||
macro TestVariableRedeclaration(context : Context) : Boolean {
|
||||
let var1 : int31 = from_constexpr<bool>(42 == 0) ? 0 : 1;
|
||||
let var2 : int31 = from_constexpr<bool>(42 == 0) ? 1 : 0;
|
||||
macro TestVariableRedeclaration(context: Context): Boolean {
|
||||
let var1: int31 = from_constexpr<bool>(42 == 0) ? 0 : 1;
|
||||
let var2: int31 = from_constexpr<bool>(42 == 0) ? 1 : 0;
|
||||
return True;
|
||||
}
|
||||
|
||||
macro TestTernaryOperator(x : Smi) : Smi {
|
||||
let b : bool = x < 0 ? true : false;
|
||||
macro TestTernaryOperator(x: Smi): Smi {
|
||||
let b: bool = x < 0 ? true : false;
|
||||
return b ? x - 10 : x + 100;
|
||||
}
|
||||
|
||||
@ -195,7 +196,7 @@ module test {
|
||||
}
|
||||
|
||||
type SmiToSmi = builtin(Smi) => Smi;
|
||||
macro TestTypeAlias(x : SmiToSmi) : Code {
|
||||
macro TestTypeAlias(x: SmiToSmi): Code {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -221,8 +222,9 @@ module test {
|
||||
|
||||
macro TestMultilineAssert() {
|
||||
let someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
|
||||
check(someVeryLongVariableNameThatWillCauseLineBreaks > 0
|
||||
&& someVeryLongVariableNameThatWillCauseLineBreaks < 10);
|
||||
check(
|
||||
someVeryLongVariableNameThatWillCauseLineBreaks > 0 &&
|
||||
someVeryLongVariableNameThatWillCauseLineBreaks < 10);
|
||||
}
|
||||
|
||||
macro TestNewlineInString() {
|
||||
@ -243,4 +245,48 @@ module test {
|
||||
const kSmi: Smi = 3;
|
||||
check(kSmi == 3);
|
||||
}
|
||||
|
||||
struct TestStructA {
|
||||
indexes: FixedArray;
|
||||
i: Smi;
|
||||
k: Number;
|
||||
}
|
||||
|
||||
struct TestStructB {
|
||||
x: TestStructA;
|
||||
y: Smi;
|
||||
}
|
||||
|
||||
macro TestStruct1(i: TestStructA): Smi {
|
||||
return i.i;
|
||||
}
|
||||
|
||||
macro TestStruct2(): TestStructA {
|
||||
return TestStructA{unsafe_cast<FixedArray>(kEmptyFixedArray), 27, 31};
|
||||
}
|
||||
|
||||
macro TestStruct3(): TestStructA {
|
||||
let a: TestStructA =
|
||||
TestStructA{unsafe_cast<FixedArray>(kEmptyFixedArray), 13, 5};
|
||||
let b: TestStructA = a;
|
||||
let c: TestStructA = TestStruct2();
|
||||
a.i = TestStruct1(c);
|
||||
a.k = a.i;
|
||||
let d: TestStructB;
|
||||
d.x = a;
|
||||
d = TestStructB{a, 7};
|
||||
let e: TestStructA = d.x;
|
||||
let f: Smi = TestStructA{unsafe_cast<FixedArray>(kEmptyFixedArray), 27, 31}.i;
|
||||
f = TestStruct2().i;
|
||||
return a;
|
||||
}
|
||||
|
||||
struct TestStructC {
|
||||
x : TestStructA;
|
||||
y : TestStructA;
|
||||
}
|
||||
|
||||
macro TestStruct4(): TestStructC {
|
||||
return TestStructC{TestStruct2(), TestStruct2()};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user