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:
@@ -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;")
|
||||
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user