Commit 1062ffb9 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[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: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54501}
parent 16af1baa
...@@ -190,9 +190,11 @@ unaryExpression ...@@ -190,9 +190,11 @@ unaryExpression
| op=(PLUS | MINUS | BIT_NOT | NOT) unaryExpression; | op=(PLUS | MINUS | BIT_NOT | NOT) unaryExpression;
locationExpression locationExpression
: IDENTIFIER genericSpecializationTypeList? : IDENTIFIER
| locationExpression '.' IDENTIFIER | locationExpression '.' IDENTIFIER
| locationExpression '[' expression ']'; | primaryExpression '.' IDENTIFIER
| locationExpression '[' expression ']'
| primaryExpression '[' expression ']';
incrementDecrement incrementDecrement
: INCREMENT locationExpression : INCREMENT locationExpression
...@@ -206,14 +208,24 @@ assignment ...@@ -206,14 +208,24 @@ assignment
| locationExpression ((ASSIGNMENT | ASSIGNMENT_OPERATOR) expression)?; | locationExpression ((ASSIGNMENT | ASSIGNMENT_OPERATOR) expression)?;
assignmentExpression assignmentExpression
: primaryExpression : functionPointerExpression
| assignment; | assignment;
structExpression
: IDENTIFIER '{' (expression (',' expression)*)? '}';
functionPointerExpression
: primaryExpression
| IDENTIFIER genericSpecializationTypeList?
;
primaryExpression primaryExpression
: helperCall : helperCall
| structExpression
| DECIMAL_LITERAL | DECIMAL_LITERAL
| STRING_LITERAL | STRING_LITERAL
| ('(' expression ')'); | ('(' expression ')')
;
forInitialization : variableDeclarationWithInitialization?; forInitialization : variableDeclarationWithInitialization?;
forLoop: FOR '(' forInitialization ';' expression ';' assignment ')' statementBlock; forLoop: FOR '(' forInitialization ';' expression ';' assignment ')' statementBlock;
...@@ -266,6 +278,9 @@ statementBlock ...@@ -266,6 +278,9 @@ statementBlock
helperBody : statementScope; helperBody : statementScope;
fieldDeclaration: IDENTIFIER ':' type ';';
fieldListDeclaration: fieldDeclaration*;
extendsDeclaration: 'extends' IDENTIFIER; extendsDeclaration: 'extends' IDENTIFIER;
generatesDeclaration: 'generates' STRING_LITERAL; generatesDeclaration: 'generates' STRING_LITERAL;
constexprDeclaration: 'constexpr' STRING_LITERAL; constexprDeclaration: 'constexpr' STRING_LITERAL;
...@@ -280,9 +295,11 @@ genericSpecialization: IDENTIFIER genericSpecializationTypeList parameterList op ...@@ -280,9 +295,11 @@ genericSpecialization: IDENTIFIER genericSpecializationTypeList parameterList op
macroDeclaration : ('operator' STRING_LITERAL)? MACRO IDENTIFIER optionalGenericTypeList parameterList optionalType optionalLabelList (helperBody | ';'); macroDeclaration : ('operator' STRING_LITERAL)? MACRO IDENTIFIER optionalGenericTypeList parameterList optionalType optionalLabelList (helperBody | ';');
externConstDeclaration : CONST IDENTIFIER ':' type generatesDeclaration ';'; externConstDeclaration : CONST IDENTIFIER ':' type generatesDeclaration ';';
constDeclaration: CONST IDENTIFIER ':' type ASSIGNMENT expression ';'; constDeclaration: CONST IDENTIFIER ':' type ASSIGNMENT expression ';';
structDeclaration : 'struct' IDENTIFIER '{' fieldListDeclaration '}';
declaration declaration
: typeDeclaration : structDeclaration
| typeDeclaration
| typeAliasDeclaration | typeAliasDeclaration
| builtinDeclaration | builtinDeclaration
| genericSpecialization | genericSpecialization
......
This diff is collapsed.
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 { ...@@ -141,6 +141,16 @@ class TorqueBaseListener : public TorqueListener {
void exitAssignmentExpression( void exitAssignmentExpression(
TorqueParser::AssignmentExpressionContext* /*ctx*/) override {} 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( void enterPrimaryExpression(
TorqueParser::PrimaryExpressionContext* /*ctx*/) override {} TorqueParser::PrimaryExpressionContext* /*ctx*/) override {}
void exitPrimaryExpression( void exitPrimaryExpression(
...@@ -263,6 +273,16 @@ class TorqueBaseListener : public TorqueListener { ...@@ -263,6 +273,16 @@ class TorqueBaseListener : public TorqueListener {
void enterHelperBody(TorqueParser::HelperBodyContext* /*ctx*/) override {} void enterHelperBody(TorqueParser::HelperBodyContext* /*ctx*/) override {}
void exitHelperBody(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( void enterExtendsDeclaration(
TorqueParser::ExtendsDeclarationContext* /*ctx*/) override {} TorqueParser::ExtendsDeclarationContext* /*ctx*/) override {}
void exitExtendsDeclaration( void exitExtendsDeclaration(
...@@ -328,6 +348,11 @@ class TorqueBaseListener : public TorqueListener { ...@@ -328,6 +348,11 @@ class TorqueBaseListener : public TorqueListener {
void exitConstDeclaration( void exitConstDeclaration(
TorqueParser::ConstDeclarationContext* /*ctx*/) override {} TorqueParser::ConstDeclarationContext* /*ctx*/) override {}
void enterStructDeclaration(
TorqueParser::StructDeclarationContext* /*ctx*/) override {}
void exitStructDeclaration(
TorqueParser::StructDeclarationContext* /*ctx*/) override {}
void enterDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {} void enterDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {}
void exitDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {} void exitDeclaration(TorqueParser::DeclarationContext* /*ctx*/) override {}
......
...@@ -148,6 +148,16 @@ class TorqueBaseVisitor : public TorqueVisitor { ...@@ -148,6 +148,16 @@ class TorqueBaseVisitor : public TorqueVisitor {
return visitChildren(ctx); 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( antlrcpp::Any visitPrimaryExpression(
TorqueParser::PrimaryExpressionContext* ctx) override { TorqueParser::PrimaryExpressionContext* ctx) override {
return visitChildren(ctx); return visitChildren(ctx);
...@@ -281,6 +291,16 @@ class TorqueBaseVisitor : public TorqueVisitor { ...@@ -281,6 +291,16 @@ class TorqueBaseVisitor : public TorqueVisitor {
return visitChildren(ctx); 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( antlrcpp::Any visitExtendsDeclaration(
TorqueParser::ExtendsDeclarationContext* ctx) override { TorqueParser::ExtendsDeclarationContext* ctx) override {
return visitChildren(ctx); return visitChildren(ctx);
...@@ -346,6 +366,11 @@ class TorqueBaseVisitor : public TorqueVisitor { ...@@ -346,6 +366,11 @@ class TorqueBaseVisitor : public TorqueVisitor {
return visitChildren(ctx); return visitChildren(ctx);
} }
antlrcpp::Any visitStructDeclaration(
TorqueParser::StructDeclarationContext* ctx) override {
return visitChildren(ctx);
}
antlrcpp::Any visitDeclaration( antlrcpp::Any visitDeclaration(
TorqueParser::DeclarationContext* ctx) override { TorqueParser::DeclarationContext* ctx) override {
return visitChildren(ctx); return visitChildren(ctx);
......
This diff is collapsed.
...@@ -33,66 +33,67 @@ class TorqueLexer : public antlr4::Lexer { ...@@ -33,66 +33,67 @@ class TorqueLexer : public antlr4::Lexer {
T__17 = 18, T__17 = 18,
T__18 = 19, T__18 = 19,
T__19 = 20, T__19 = 20,
MACRO = 21, T__20 = 21,
BUILTIN = 22, MACRO = 22,
RUNTIME = 23, BUILTIN = 23,
MODULE = 24, RUNTIME = 24,
JAVASCRIPT = 25, MODULE = 25,
DEFERRED = 26, JAVASCRIPT = 26,
IF = 27, DEFERRED = 27,
FOR = 28, IF = 28,
WHILE = 29, FOR = 29,
RETURN = 30, WHILE = 30,
CONSTEXPR = 31, RETURN = 31,
CONTINUE = 32, CONSTEXPR = 32,
BREAK = 33, CONTINUE = 33,
GOTO = 34, BREAK = 34,
OTHERWISE = 35, GOTO = 35,
TRY = 36, OTHERWISE = 36,
LABEL = 37, TRY = 37,
LABELS = 38, LABEL = 38,
TAIL = 39, LABELS = 39,
ISNT = 40, TAIL = 40,
IS = 41, ISNT = 41,
LET = 42, IS = 42,
CONST = 43, LET = 43,
EXTERN = 44, CONST = 44,
ASSERT_TOKEN = 45, EXTERN = 45,
CHECK_TOKEN = 46, ASSERT_TOKEN = 46,
UNREACHABLE_TOKEN = 47, CHECK_TOKEN = 47,
DEBUG_TOKEN = 48, UNREACHABLE_TOKEN = 48,
ASSIGNMENT = 49, DEBUG_TOKEN = 49,
ASSIGNMENT_OPERATOR = 50, ASSIGNMENT = 50,
EQUAL = 51, ASSIGNMENT_OPERATOR = 51,
PLUS = 52, EQUAL = 52,
MINUS = 53, PLUS = 53,
MULTIPLY = 54, MINUS = 54,
DIVIDE = 55, MULTIPLY = 55,
MODULO = 56, DIVIDE = 56,
BIT_OR = 57, MODULO = 57,
BIT_AND = 58, BIT_OR = 58,
BIT_NOT = 59, BIT_AND = 59,
MAX = 60, BIT_NOT = 60,
MIN = 61, MAX = 61,
NOT_EQUAL = 62, MIN = 62,
LESS_THAN = 63, NOT_EQUAL = 63,
LESS_THAN_EQUAL = 64, LESS_THAN = 64,
GREATER_THAN = 65, LESS_THAN_EQUAL = 65,
GREATER_THAN_EQUAL = 66, GREATER_THAN = 66,
SHIFT_LEFT = 67, GREATER_THAN_EQUAL = 67,
SHIFT_RIGHT = 68, SHIFT_LEFT = 68,
SHIFT_RIGHT_ARITHMETIC = 69, SHIFT_RIGHT = 69,
VARARGS = 70, SHIFT_RIGHT_ARITHMETIC = 70,
EQUALITY_OPERATOR = 71, VARARGS = 71,
INCREMENT = 72, EQUALITY_OPERATOR = 72,
DECREMENT = 73, INCREMENT = 73,
NOT = 74, DECREMENT = 74,
STRING_LITERAL = 75, NOT = 75,
IDENTIFIER = 76, STRING_LITERAL = 76,
WS = 77, IDENTIFIER = 77,
BLOCK_COMMENT = 78, WS = 78,
LINE_COMMENT = 79, BLOCK_COMMENT = 79,
DECIMAL_LITERAL = 80 LINE_COMMENT = 80,
DECIMAL_LITERAL = 81
}; };
explicit TorqueLexer(antlr4::CharStream* input); explicit TorqueLexer(antlr4::CharStream* input);
......
This diff is collapsed.
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 { ...@@ -137,6 +137,16 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
virtual void exitAssignmentExpression( virtual void exitAssignmentExpression(
TorqueParser::AssignmentExpressionContext* ctx) = 0; 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( virtual void enterPrimaryExpression(
TorqueParser::PrimaryExpressionContext* ctx) = 0; TorqueParser::PrimaryExpressionContext* ctx) = 0;
virtual void exitPrimaryExpression( virtual void exitPrimaryExpression(
...@@ -248,6 +258,16 @@ class TorqueListener : public antlr4::tree::ParseTreeListener { ...@@ -248,6 +258,16 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
virtual void enterHelperBody(TorqueParser::HelperBodyContext* ctx) = 0; virtual void enterHelperBody(TorqueParser::HelperBodyContext* ctx) = 0;
virtual void exitHelperBody(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( virtual void enterExtendsDeclaration(
TorqueParser::ExtendsDeclarationContext* ctx) = 0; TorqueParser::ExtendsDeclarationContext* ctx) = 0;
virtual void exitExtendsDeclaration( virtual void exitExtendsDeclaration(
...@@ -311,6 +331,11 @@ class TorqueListener : public antlr4::tree::ParseTreeListener { ...@@ -311,6 +331,11 @@ class TorqueListener : public antlr4::tree::ParseTreeListener {
virtual void exitConstDeclaration( virtual void exitConstDeclaration(
TorqueParser::ConstDeclarationContext* ctx) = 0; 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 enterDeclaration(TorqueParser::DeclarationContext* ctx) = 0;
virtual void exitDeclaration(TorqueParser::DeclarationContext* ctx) = 0; virtual void exitDeclaration(TorqueParser::DeclarationContext* ctx) = 0;
......
This diff is collapsed.
This diff is collapsed.
...@@ -100,6 +100,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor { ...@@ -100,6 +100,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
virtual antlrcpp::Any visitAssignmentExpression( virtual antlrcpp::Any visitAssignmentExpression(
TorqueParser::AssignmentExpressionContext* context) = 0; TorqueParser::AssignmentExpressionContext* context) = 0;
virtual antlrcpp::Any visitStructExpression(
TorqueParser::StructExpressionContext* context) = 0;
virtual antlrcpp::Any visitFunctionPointerExpression(
TorqueParser::FunctionPointerExpressionContext* context) = 0;
virtual antlrcpp::Any visitPrimaryExpression( virtual antlrcpp::Any visitPrimaryExpression(
TorqueParser::PrimaryExpressionContext* context) = 0; TorqueParser::PrimaryExpressionContext* context) = 0;
...@@ -183,6 +189,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor { ...@@ -183,6 +189,12 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
virtual antlrcpp::Any visitHelperBody( virtual antlrcpp::Any visitHelperBody(
TorqueParser::HelperBodyContext* context) = 0; TorqueParser::HelperBodyContext* context) = 0;
virtual antlrcpp::Any visitFieldDeclaration(
TorqueParser::FieldDeclarationContext* context) = 0;
virtual antlrcpp::Any visitFieldListDeclaration(
TorqueParser::FieldListDeclarationContext* context) = 0;
virtual antlrcpp::Any visitExtendsDeclaration( virtual antlrcpp::Any visitExtendsDeclaration(
TorqueParser::ExtendsDeclarationContext* context) = 0; TorqueParser::ExtendsDeclarationContext* context) = 0;
...@@ -222,6 +234,9 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor { ...@@ -222,6 +234,9 @@ class TorqueVisitor : public antlr4::tree::AbstractParseTreeVisitor {
virtual antlrcpp::Any visitConstDeclaration( virtual antlrcpp::Any visitConstDeclaration(
TorqueParser::ConstDeclarationContext* context) = 0; TorqueParser::ConstDeclarationContext* context) = 0;
virtual antlrcpp::Any visitStructDeclaration(
TorqueParser::StructDeclarationContext* context) = 0;
virtual antlrcpp::Any visitDeclaration( virtual antlrcpp::Any visitDeclaration(
TorqueParser::DeclarationContext* context) = 0; TorqueParser::DeclarationContext* context) = 0;
......
...@@ -545,6 +545,21 @@ antlrcpp::Any AstGenerator::visitTryLabelStatement( ...@@ -545,6 +545,21 @@ antlrcpp::Any AstGenerator::visitTryLabelStatement(
return implicit_cast<Statement*>(result); 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( antlrcpp::Any AstGenerator::visitPrimaryExpression(
TorqueParser::PrimaryExpressionContext* context) { TorqueParser::PrimaryExpressionContext* context) {
if (auto* e = context->helperCall()) return e->accept(this); if (auto* e = context->helperCall()) return e->accept(this);
...@@ -554,9 +569,23 @@ antlrcpp::Any AstGenerator::visitPrimaryExpression( ...@@ -554,9 +569,23 @@ antlrcpp::Any AstGenerator::visitPrimaryExpression(
if (auto* e = context->STRING_LITERAL()) if (auto* e = context->STRING_LITERAL())
return implicit_cast<Expression*>(RegisterNode( return implicit_cast<Expression*>(RegisterNode(
new StringLiteralExpression{Pos(context), e->getSymbol()->getText()})); new StringLiteralExpression{Pos(context), e->getSymbol()->getText()}));
if (context->structExpression()) {
return context->structExpression()->accept(this);
}
return context->expression()->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( antlrcpp::Any AstGenerator::visitAssignment(
TorqueParser::AssignmentContext* context) { TorqueParser::AssignmentContext* context) {
if (auto* e = context->incrementDecrement()) return e->accept(this); if (auto* e = context->incrementDecrement()) return e->accept(this);
...@@ -589,25 +618,23 @@ antlrcpp::Any AstGenerator::visitIncrementDecrement( ...@@ -589,25 +618,23 @@ antlrcpp::Any AstGenerator::visitIncrementDecrement(
antlrcpp::Any AstGenerator::visitLocationExpression( antlrcpp::Any AstGenerator::visitLocationExpression(
TorqueParser::LocationExpressionContext* context) { TorqueParser::LocationExpressionContext* context) {
if (auto* l = context->locationExpression()) { Expression* location = nullptr;
Expression* location = l->accept(this).as<Expression*>(); 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(), {}}));
}
if (auto* e = context->expression()) { if (auto* e = context->expression()) {
return implicit_cast<Expression*>( return implicit_cast<Expression*>(RegisterNode(new ElementAccessExpression{
RegisterNode(new ElementAccessExpression{
Pos(context), location, e->accept(this).as<Expression*>()})); Pos(context), location, e->accept(this).as<Expression*>()}));
} }
return implicit_cast<Expression*>(RegisterNode(new FieldAccessExpression{ return implicit_cast<Expression*>(RegisterNode(new FieldAccessExpression{
Pos(context), location, Pos(context), location, context->IDENTIFIER()->getSymbol()->getText()}));
context->IDENTIFIER()->getSymbol()->getText()}));
}
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)}));
} }
antlrcpp::Any AstGenerator::visitUnaryExpression( antlrcpp::Any AstGenerator::visitUnaryExpression(
...@@ -768,6 +795,22 @@ antlrcpp::Any AstGenerator::visitDiagnosticStatement( ...@@ -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) { void AstGenerator::visitSourceFile(SourceFileContext* context) {
source_file_context_ = context; source_file_context_ = context;
current_source_file_ = SourceFileMap::Get().AddSource(context->name); current_source_file_ = SourceFileMap::Get().AddSource(context->name);
......
...@@ -69,6 +69,9 @@ class AstGenerator : public TorqueBaseVisitor { ...@@ -69,6 +69,9 @@ class AstGenerator : public TorqueBaseVisitor {
antlrcpp::Any visitHelperCallStatement( antlrcpp::Any visitHelperCallStatement(
TorqueParser::HelperCallStatementContext* context) override; TorqueParser::HelperCallStatementContext* context) override;
antlrcpp::Any visitStructExpression(
TorqueParser::StructExpressionContext* context) override;
antlrcpp::Any visitConditionalExpression( antlrcpp::Any visitConditionalExpression(
TorqueParser::ConditionalExpressionContext* context) override; TorqueParser::ConditionalExpressionContext* context) override;
...@@ -108,6 +111,9 @@ class AstGenerator : public TorqueBaseVisitor { ...@@ -108,6 +111,9 @@ class AstGenerator : public TorqueBaseVisitor {
antlrcpp::Any visitAssignment( antlrcpp::Any visitAssignment(
TorqueParser::AssignmentContext* context) override; TorqueParser::AssignmentContext* context) override;
antlrcpp::Any visitFunctionPointerExpression(
TorqueParser::FunctionPointerExpressionContext* context) override;
antlrcpp::Any visitPrimaryExpression( antlrcpp::Any visitPrimaryExpression(
TorqueParser::PrimaryExpressionContext* context) override; TorqueParser::PrimaryExpressionContext* context) override;
...@@ -146,6 +152,9 @@ class AstGenerator : public TorqueBaseVisitor { ...@@ -146,6 +152,9 @@ class AstGenerator : public TorqueBaseVisitor {
antlrcpp::Any visitDiagnosticStatement( antlrcpp::Any visitDiagnosticStatement(
TorqueParser::DiagnosticStatementContext* context) override; TorqueParser::DiagnosticStatementContext* context) override;
antlrcpp::Any visitStructDeclaration(
TorqueParser::StructDeclarationContext* context) override;
antlrcpp::Any aggregateResult(antlrcpp::Any aggregate, antlrcpp::Any aggregateResult(antlrcpp::Any aggregate,
const antlrcpp::Any& nextResult) override { const antlrcpp::Any& nextResult) override {
if (aggregate.isNull()) if (aggregate.isNull())
......
...@@ -29,6 +29,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition) ...@@ -29,6 +29,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition)
#define AST_EXPRESSION_NODE_KIND_LIST(V) \ #define AST_EXPRESSION_NODE_KIND_LIST(V) \
V(CallExpression) \ V(CallExpression) \
V(StructExpression) \
V(LogicalOrExpression) \ V(LogicalOrExpression) \
V(LogicalAndExpression) \ V(LogicalAndExpression) \
V(ConditionalExpression) \ V(ConditionalExpression) \
...@@ -69,6 +70,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition) ...@@ -69,6 +70,7 @@ DECLARE_CONTEXTUAL_VARIABLE(CurrentSourcePosition, SourcePosition)
V(GenericDeclaration) \ V(GenericDeclaration) \
V(SpecializationDeclaration) \ V(SpecializationDeclaration) \
V(ExternConstDeclaration) \ V(ExternConstDeclaration) \
V(StructDeclaration) \
V(DefaultModuleDeclaration) \ V(DefaultModuleDeclaration) \
V(ExplicitModuleDeclaration) \ V(ExplicitModuleDeclaration) \
V(ConstDeclaration) V(ConstDeclaration)
...@@ -260,6 +262,14 @@ struct CallExpression : Expression { ...@@ -260,6 +262,14 @@ struct CallExpression : Expression {
std::vector<std::string> labels; 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 { struct LogicalOrExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalOrExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalOrExpression)
LogicalOrExpression(SourcePosition p, Expression* l, Expression* r) LogicalOrExpression(SourcePosition p, Expression* l, Expression* r)
...@@ -552,6 +562,11 @@ struct TypeAliasDeclaration : Declaration { ...@@ -552,6 +562,11 @@ struct TypeAliasDeclaration : Declaration {
TypeExpression* type; TypeExpression* type;
}; };
struct FieldNameAndType {
std::string name;
TypeExpression* type;
};
struct LabelAndTypes { struct LabelAndTypes {
std::string name; std::string name;
std::vector<TypeExpression*> types; std::vector<TypeExpression*> types;
...@@ -693,6 +708,14 @@ struct ExternConstDeclaration : Declaration { ...@@ -693,6 +708,14 @@ struct ExternConstDeclaration : Declaration {
std::string literal; 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) \ #define ENUM_ITEM(name) \
case AstNode::Kind::k##name: \ case AstNode::Kind::k##name: \
return std::is_base_of<T, name>::value; \ return std::is_base_of<T, name>::value; \
......
...@@ -34,6 +34,18 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) { ...@@ -34,6 +34,18 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
return os; 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) { void PrintLabel(std::ostream& os, const Label& l, bool with_names) {
os << l.name(); os << l.name();
if (l.GetParameterCount() != 0) { if (l.GetParameterCount() != 0) {
......
...@@ -134,14 +134,7 @@ class Variable : public Value { ...@@ -134,14 +134,7 @@ class Variable : public Value {
DECLARE_DECLARABLE_BOILERPLATE(Variable, variable); DECLARE_DECLARABLE_BOILERPLATE(Variable, variable);
bool IsConst() const override { return const_; } bool IsConst() const override { return const_; }
std::string value() const override { return value_; } std::string value() const override { return value_; }
std::string RValue() const override { std::string RValue() const override;
if (!IsDefined()) {
ReportError("Reading uninitialized variable.");
}
std::string result = "(*" + value() + ")";
if (!IsConst()) result += ".value()";
return result;
}
void Define() { void Define() {
if (defined_ && IsConst()) { if (defined_ && IsConst()) {
ReportError("Cannot re-define a const-bound variable."); ReportError("Cannot re-define a const-bound variable.");
......
...@@ -95,6 +95,15 @@ Builtin* DeclarationVisitor::BuiltinDeclarationCommon( ...@@ -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( std::string generated_name = GetGeneratedCallableName(
decl->name, declarations()->GetCurrentSpecializationTypeNamesVector()); decl->name, declarations()->GetCurrentSpecializationTypeNamesVector());
return declarations()->DeclareBuiltin(generated_name, kind, external, return declarations()->DeclareBuiltin(generated_name, kind, external,
...@@ -117,6 +126,15 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl, ...@@ -117,6 +126,15 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
ReportError(stream.str()); 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); declarations()->DeclareRuntimeFunction(decl->name, signature);
} }
...@@ -158,8 +176,8 @@ void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl, ...@@ -158,8 +176,8 @@ void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
DeclareSignature(signature); DeclareSignature(signature);
Variable* return_variable = nullptr; Variable* return_variable = nullptr;
if (!signature.return_type->IsVoidOrNever()) { if (!signature.return_type->IsVoidOrNever()) {
return_variable = declarations()->DeclareVariable( return_variable =
kReturnValueVariable, signature.return_type, DeclareVariable(kReturnValueVariable, signature.return_type,
signature.return_type->IsConstexpr()); signature.return_type->IsConstexpr());
} }
...@@ -252,6 +270,33 @@ void DeclarationVisitor::Visit(ReturnStatement* stmt) { ...@@ -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) { void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) {
std::string variable_name = stmt->name; std::string variable_name = stmt->name;
const Type* type = declarations()->GetType(stmt->type); const Type* type = declarations()->GetType(stmt->type);
...@@ -259,7 +304,7 @@ void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) { ...@@ -259,7 +304,7 @@ void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) {
ReportError( ReportError(
"cannot declare variable with constexpr type. Use 'const' instead."); "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()) { if (global_context_.verbose()) {
std::cout << "declared variable " << variable_name << " with type " << *type std::cout << "declared variable " << variable_name << " with type " << *type
<< "\n"; << "\n";
...@@ -293,6 +338,15 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) { ...@@ -293,6 +338,15 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
declarations()->DeclareExternConstant(decl->name, type, decl->literal); 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) { void DeclarationVisitor::Visit(LogicalOrExpression* expr) {
{ {
Declarations::NodeScopeActivator scope(declarations(), expr->left); Declarations::NodeScopeActivator scope(declarations(), expr->left);
...@@ -415,8 +469,7 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) { ...@@ -415,8 +469,7 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) {
ReportError("no constexpr type allowed for label arguments"); ReportError("no constexpr type allowed for label arguments");
} }
shared_label->AddVariable( shared_label->AddVariable(DeclareVariable(p, type, false));
declarations()->DeclareVariable(p, type, false));
++i; ++i;
} }
} }
...@@ -556,8 +609,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) { ...@@ -556,8 +609,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) {
for (auto name : signature.parameter_names) { for (auto name : signature.parameter_names) {
const Type* t(*type_iterator++); const Type* t(*type_iterator++);
if (name.size() != 0) { if (name.size() != 0) {
declarations()->DeclareParameter(name, GetParameterVariableFromName(name), DeclareParameter(name, t);
t);
} }
} }
for (auto& label : signature.labels) { for (auto& label : signature.labels) {
...@@ -570,8 +622,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) { ...@@ -570,8 +622,7 @@ void DeclarationVisitor::DeclareSignature(const Signature& signature) {
} }
std::string var_name = label.name + std::to_string(i++); std::string var_name = label.name + std::to_string(i++);
new_label->AddVariable( new_label->AddVariable(DeclareVariable(var_name, var_type, false));
declarations()->DeclareVariable(var_name, var_type, false));
} }
} }
} }
......
...@@ -108,6 +108,10 @@ class DeclarationVisitor : public FileVisitor { ...@@ -108,6 +108,10 @@ class DeclarationVisitor : public FileVisitor {
void Visit(VarDeclarationStatement* stmt); void Visit(VarDeclarationStatement* stmt);
void Visit(ExternConstDeclaration* decl); void Visit(ExternConstDeclaration* decl);
void Visit(StructDeclaration* decl);
void Visit(StructExpression* decl) {}
void Visit(LogicalOrExpression* expr); void Visit(LogicalOrExpression* expr);
void Visit(LogicalAndExpression* expr); void Visit(LogicalAndExpression* expr);
void DeclareExpressionForBranch(Expression* node); void DeclareExpressionForBranch(Expression* node);
...@@ -148,6 +152,10 @@ class DeclarationVisitor : public FileVisitor { ...@@ -148,6 +152,10 @@ class DeclarationVisitor : public FileVisitor {
live_and_changed_variables_.push_back(live_and_changed); 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() { std::set<const Variable*> PopControlSplit() {
auto result = live_and_changed_variables_.back().changed; auto result = live_and_changed_variables_.back().changed;
live_and_changed_variables_.pop_back(); live_and_changed_variables_.pop_back();
......
...@@ -224,6 +224,12 @@ void Declarations::DeclareType(const std::string& name, const Type* type) { ...@@ -224,6 +224,12 @@ void Declarations::DeclareType(const std::string& name, const Type* type) {
Declare(name, std::unique_ptr<TypeAlias>(result)); 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) { Label* Declarations::DeclareLabel(const std::string& name) {
CheckAlreadyDeclared(name, "label"); CheckAlreadyDeclared(name, "label");
Label* result = new Label(name); Label* result = new Label(name);
...@@ -289,7 +295,9 @@ RuntimeFunction* Declarations::DeclareRuntimeFunction( ...@@ -289,7 +295,9 @@ RuntimeFunction* Declarations::DeclareRuntimeFunction(
Variable* Declarations::DeclareVariable(const std::string& var, Variable* Declarations::DeclareVariable(const std::string& var,
const Type* type, bool is_const) { 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"); CheckAlreadyDeclared(var, "variable");
Variable* result = new Variable(var, name, type, is_const); Variable* result = new Variable(var, name, type, is_const);
Declare(var, std::unique_ptr<Declarable>(result)); Declare(var, std::unique_ptr<Declarable>(result));
......
...@@ -76,6 +76,9 @@ class Declarations { ...@@ -76,6 +76,9 @@ class Declarations {
void DeclareType(const std::string& name, const Type* type); 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); Label* DeclareLabel(const std::string& name);
Macro* DeclareMacro(const std::string& name, const Signature& signature, Macro* DeclareMacro(const std::string& name, const Signature& signature,
......
This diff is collapsed.
...@@ -37,35 +37,31 @@ class ImplementationVisitor : public FileVisitor { ...@@ -37,35 +37,31 @@ class ImplementationVisitor : public FileVisitor {
const Type* Visit(Statement* stmt); const Type* Visit(Statement* stmt);
void Visit(Declaration* decl); void Visit(Declaration* decl);
VisitResult Visit(StructExpression* decl);
LocationReference GetLocationReference(LocationExpression* location); LocationReference GetLocationReference(LocationExpression* location);
LocationReference GetLocationReference(IdentifierExpression* expr) { LocationReference GetLocationReference(IdentifierExpression* expr) {
return LocationReference(declarations()->LookupValue(expr->name), {}, {}); return LocationReference(declarations()->LookupValue(expr->name), {}, {});
} }
LocationReference GetLocationReference(FieldAccessExpression* expr) { LocationReference GetLocationReference(FieldAccessExpression* expr);
return LocationReference({}, Visit(expr->object), {});
}
LocationReference GetLocationReference(ElementAccessExpression* expr) { LocationReference GetLocationReference(ElementAccessExpression* expr) {
return LocationReference({}, Visit(expr->array), Visit(expr->index)); 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, VisitResult GenerateFetchFromLocation(LocationExpression* location,
LocationReference reference); LocationReference reference);
VisitResult GenerateFetchFromLocation(IdentifierExpression* expr, VisitResult GenerateFetchFromLocation(IdentifierExpression* expr,
LocationReference reference) { LocationReference reference) {
Value* value = reference.value; return GenerateFetchFromLocation(reference);
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);
} }
VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr, VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr,
LocationReference reference) { LocationReference reference);
Arguments arguments;
arguments.parameters = {reference.base};
return GenerateCall(std::string(".") + expr->field, arguments);
}
VisitResult GenerateFetchFromLocation(ElementAccessExpression* expr, VisitResult GenerateFetchFromLocation(ElementAccessExpression* expr,
LocationReference reference) { LocationReference reference) {
Arguments arguments; Arguments arguments;
...@@ -93,6 +89,7 @@ class ImplementationVisitor : public FileVisitor { ...@@ -93,6 +89,7 @@ class ImplementationVisitor : public FileVisitor {
void Visit(TypeDeclaration* decl) {} void Visit(TypeDeclaration* decl) {}
void Visit(TypeAliasDeclaration* decl) {} void Visit(TypeAliasDeclaration* decl) {}
void Visit(ExternConstDeclaration* decl) {} void Visit(ExternConstDeclaration* decl) {}
void Visit(StructDeclaration* decl);
void Visit(StandardDeclaration* decl); void Visit(StandardDeclaration* decl);
void Visit(GenericDeclaration* decl) {} void Visit(GenericDeclaration* decl) {}
void Visit(SpecializationDeclaration* decl); void Visit(SpecializationDeclaration* decl);
...@@ -176,6 +173,11 @@ class ImplementationVisitor : public FileVisitor { ...@@ -176,6 +173,11 @@ class ImplementationVisitor : public FileVisitor {
Callable* LookupCall(const std::string& name, const Arguments& arguments); 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); void GenerateChangedVarsFromControlSplit(AstNode* node);
const Type* GetCommonType(const Type* left, const Type* right); const Type* GetCommonType(const Type* left, const Type* right);
...@@ -188,6 +190,8 @@ class ImplementationVisitor : public FileVisitor { ...@@ -188,6 +190,8 @@ class ImplementationVisitor : public FileVisitor {
const LocationReference& reference, const LocationReference& reference,
VisitResult assignment_value); VisitResult assignment_value);
void GenerateVariableDeclaration(const Variable* var);
Variable* GenerateVariableDeclaration( Variable* GenerateVariableDeclaration(
AstNode* node, const std::string& name, AstNode* node, const std::string& name,
const base::Optional<const Type*>& type, const base::Optional<const Type*>& type,
......
...@@ -29,6 +29,14 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -29,6 +29,14 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return result; 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( static const FunctionPointerType* GetFunctionPointerType(
TypeVector argument_types, const Type* return_type) { TypeVector argument_types, const Type* return_type) {
const Type* code_type = Get().GetBuiltinType(CODE_TYPE_STRING); const Type* code_type = Get().GetBuiltinType(CODE_TYPE_STRING);
...@@ -101,6 +109,7 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -101,6 +109,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
Deduplicator<FunctionPointerType> function_pointer_types_; Deduplicator<FunctionPointerType> function_pointer_types_;
Deduplicator<UnionType> union_types_; Deduplicator<UnionType> union_types_;
std::vector<std::unique_ptr<Type>> nominal_types_; std::vector<std::unique_ptr<Type>> nominal_types_;
std::vector<std::unique_ptr<Type>> struct_types_;
}; };
} // namespace torque } // namespace torque
......
...@@ -154,6 +154,14 @@ const Type* UnionType::NonConstexprVersion() const { ...@@ -154,6 +154,14 @@ const Type* UnionType::NonConstexprVersion() const {
return this; 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) { void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
os << "("; os << "(";
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) { 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) { ...@@ -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) { std::ostream& operator<<(std::ostream& os, const Signature& sig) {
PrintSignature(os, sig, true); PrintSignature(os, sig, true);
return os; return os;
...@@ -256,7 +271,17 @@ std::string VisitResult::LValue() const { ...@@ -256,7 +271,17 @@ std::string VisitResult::LValue() const {
} }
std::string VisitResult::RValue() 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 } // namespace torque
......
...@@ -37,13 +37,19 @@ class Value; ...@@ -37,13 +37,19 @@ class Value;
class TypeBase { class TypeBase {
public: public:
enum class Kind { kAbstractType, kFunctionPointerType, kUnionType }; enum class Kind {
kAbstractType,
kFunctionPointerType,
kUnionType,
kStructType
};
virtual ~TypeBase() {} virtual ~TypeBase() {}
bool IsAbstractType() const { return kind() == Kind::kAbstractType; } bool IsAbstractType() const { return kind() == Kind::kAbstractType; }
bool IsFunctionPointerType() const { bool IsFunctionPointerType() const {
return kind() == Kind::kFunctionPointerType; return kind() == Kind::kFunctionPointerType;
} }
bool IsUnionType() const { return kind() == Kind::kUnionType; } bool IsUnionType() const { return kind() == Kind::kUnionType; }
bool IsStructType() const { return kind() == Kind::kStructType; }
protected: protected:
explicit TypeBase(Kind kind) : kind_(kind) {} explicit TypeBase(Kind kind) : kind_(kind) {}
...@@ -111,6 +117,13 @@ class Type : public TypeBase { ...@@ -111,6 +117,13 @@ class Type : public TypeBase {
using TypeVector = std::vector<const Type*>; 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 { class AbstractType final : public Type {
public: public:
DECLARE_TYPE_BOILERPLATE(AbstractType); DECLARE_TYPE_BOILERPLATE(AbstractType);
...@@ -285,6 +298,37 @@ class UnionType final : public Type { ...@@ -285,6 +298,37 @@ class UnionType final : public Type {
std::set<const Type*, TypeLess> types_; 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) { inline std::ostream& operator<<(std::ostream& os, const Type& t) {
os << t.ToString(); os << t.ToString();
return os; return os;
...@@ -325,11 +369,6 @@ class VisitResultVector : public std::vector<VisitResult> { ...@@ -325,11 +369,6 @@ class VisitResultVector : public std::vector<VisitResult> {
std::ostream& operator<<(std::ostream& os, const TypeVector& types); std::ostream& operator<<(std::ostream& os, const TypeVector& types);
struct NameAndType {
std::string name;
const Type* type;
};
typedef std::vector<NameAndType> NameAndTypeVector; typedef std::vector<NameAndType> NameAndTypeVector;
struct LabelDefinition { struct LabelDefinition {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
module test { module test {
macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool { macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) { if constexpr((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
return true; return true;
} }
else { else {
...@@ -82,7 +82,7 @@ module test { ...@@ -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; return Null;
} }
...@@ -98,7 +98,8 @@ module test { ...@@ -98,7 +98,8 @@ module test {
} }
macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 { macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 {
if constexpr (flag) goto Label4; if
constexpr(flag) goto Label4;
else else
goto Label5; goto Label5;
} }
...@@ -125,7 +126,7 @@ module test { ...@@ -125,7 +126,7 @@ module test {
return False; return False;
} }
macro GenericMacroTest<T: type>(param: T): Object { macro GenericMacroTest<T : type>(param: T): Object {
return Undefined; return Undefined;
} }
...@@ -133,7 +134,7 @@ module test { ...@@ -133,7 +134,7 @@ module test {
return param2; return param2;
} }
macro GenericMacroTestWithLabels<T: type>(param: T): Object labels X { macro GenericMacroTestWithLabels<T : type>(param: T): Object labels X {
return Undefined; return Undefined;
} }
...@@ -158,29 +159,29 @@ module test { ...@@ -158,29 +159,29 @@ module test {
} }
} }
builtin TestHelperPlus1(context : Context, x : Smi) : Smi { builtin TestHelperPlus1(context: Context, x: Smi): Smi {
return x + 1; return x + 1;
} }
builtin TestHelperPlus2(context : Context, x : Smi) : Smi { builtin TestHelperPlus2(context: Context, x: Smi): Smi {
return x + 2; return x + 2;
} }
macro TestFunctionPointers(context : Context) : Boolean { macro TestFunctionPointers(context: Context): Boolean {
let fptr : builtin(Context, Smi) => Smi = TestHelperPlus1; let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
check(fptr(context, 42) == 43); check(fptr(context, 42) == 43);
fptr = TestHelperPlus2; fptr = TestHelperPlus2;
check(fptr(context, 42) == 44); check(fptr(context, 42) == 44);
return True; return True;
} }
macro TestVariableRedeclaration(context : Context) : Boolean { macro TestVariableRedeclaration(context: Context): Boolean {
let var1 : int31 = from_constexpr<bool>(42 == 0) ? 0 : 1; let var1: int31 = from_constexpr<bool>(42 == 0) ? 0 : 1;
let var2 : int31 = from_constexpr<bool>(42 == 0) ? 1 : 0; let var2: int31 = from_constexpr<bool>(42 == 0) ? 1 : 0;
return True; return True;
} }
macro TestTernaryOperator(x : Smi) : Smi { macro TestTernaryOperator(x: Smi): Smi {
let b : bool = x < 0 ? true : false; let b: bool = x < 0 ? true : false;
return b ? x - 10 : x + 100; return b ? x - 10 : x + 100;
} }
...@@ -195,7 +196,7 @@ module test { ...@@ -195,7 +196,7 @@ module test {
} }
type SmiToSmi = builtin(Smi) => Smi; type SmiToSmi = builtin(Smi) => Smi;
macro TestTypeAlias(x : SmiToSmi) : Code { macro TestTypeAlias(x: SmiToSmi): Code {
return x; return x;
} }
...@@ -221,8 +222,9 @@ module test { ...@@ -221,8 +222,9 @@ module test {
macro TestMultilineAssert() { macro TestMultilineAssert() {
let someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5; let someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5;
check(someVeryLongVariableNameThatWillCauseLineBreaks > 0 check(
&& someVeryLongVariableNameThatWillCauseLineBreaks < 10); someVeryLongVariableNameThatWillCauseLineBreaks > 0 &&
someVeryLongVariableNameThatWillCauseLineBreaks < 10);
} }
macro TestNewlineInString() { macro TestNewlineInString() {
...@@ -243,4 +245,48 @@ module test { ...@@ -243,4 +245,48 @@ module test {
const kSmi: Smi = 3; const kSmi: Smi = 3;
check(kSmi == 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()};
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment