mem-ruby: Re-enable assign with implicit_ctor structures (#1694)

In #1453, an `implicit_ctor` option was added for SLICC structures. This
was done to allow statements such as `NetDest tmp;` which now require a
non-default constructor without modifying every protocol. The new
`implicit_ctor` option converts the statement `NetDest tmp;` in SLICC to
`NetDest tmp(<implicit_ctor>);` in C++. This is problematic when doing
something like `NetDest tmp := getMachines(...);` which gets converted
to `NetDest tmp(<implicit_ctor) = getMachines(...);` as the constructor
doesn't return an object. Before #1453 NetDest had a default constructor
so there we no difference between a local variable definition and local
variable assignment.

This commit fixes this issue by checking in the LocalVariableAST if the
local variable is part of an assignment or not. If it is not part of an
assignment, the implicit_ctor is used. Otherwise, the assignment is
printed to the generated code.

Note that this is not done anywhere in the public code but should be
allowed for folks writing their own Ruby protocols who might otherwise
be confused why a simple assignment presents a compile error.
This commit is contained in:
Matthew Poremba
2024-10-29 08:53:14 -07:00
committed by GitHub
parent 853f2ea012
commit 1442a4dccd
3 changed files with 4 additions and 4 deletions

View File

@@ -41,8 +41,8 @@ class AssignStatementAST(StatementAST):
lcode = self.slicc.codeFormatter()
rcode = self.slicc.codeFormatter()
ltype = self.lvalue.generate(lcode)
rtype = self.rvalue.generate(rcode)
ltype = self.lvalue.generate(lcode, is_assign=True)
rtype = self.rvalue.generate(rcode, is_assign=True)
code("$lcode = $rcode;")

View File

@@ -73,7 +73,7 @@ class LocalVariableAST(StatementAST):
)
):
code += f"{type.c_ident}* {ident}"
elif "implicit_ctor" in type:
elif "implicit_ctor" in type and not "is_assign" in kwargs:
code += f"{type.c_ident} {ident}({type['implicit_ctor']})"
else:
code += f"{type.c_ident} {ident}"

View File

@@ -38,7 +38,7 @@ class MemberExprAST(ExprAST):
def __repr__(self):
return f"[MemberExprAST: {self.expr_ast!r}.{self.field!r}]"
def generate(self, code):
def generate(self, code, **kwargs):
return_type, gcode = self.expr_ast.inline(True)
fix = code.nofix()