From 605081b7590426135758ab4bf364f085e20c2cab Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Sun, 13 Feb 2022 21:21:27 +0000 Subject: [PATCH] Deep struct equality, and union equality, in JavaScript backend. --- TODO.md | 2 -- src/castile/backends/javascript.py | 19 ++++++++++++++++--- test.sh | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index 4c4cdde..632ee88 100644 --- a/TODO.md +++ b/TODO.md @@ -11,8 +11,6 @@ Figure out a way to do `input`, `read`, and `write` with node.js backend. Implement `int`, `chr`, `ord` for Ruby, JavaScript, stackmac, C. -Struct equality is not properly deep in JavaScript or C. - Better indentation in the JavaScript backend. TaggedValue -> just a tuple. diff --git a/src/castile/backends/javascript.py b/src/castile/backends/javascript.py index d1e33fd..af789ae 100644 --- a/src/castile/backends/javascript.py +++ b/src/castile/backends/javascript.py @@ -1,4 +1,4 @@ -from castile.types import Struct +from castile.types import Struct, Union OPS = { 'and': '&&', @@ -56,6 +56,10 @@ def compile(self, ast): } }; +var equal_tagged_value = function(tv1, tv2) +{ + return (tv1.tag === tv2.tag) && (tv1.value === tv2.value); +} """) for child in ast.children: self.compile(child) @@ -75,8 +79,11 @@ def compile(self, ast): self.out.write('function equal_%s(a, b) {\n' % ast.value) for child in ast.children: assert child.tag == 'FieldDefn' - # TODO does not handle structs within structs - self.out.write('if (a.%s !== b.%s) return false;\n' % (child.value, child.value)) + struct_type = child.children[0].value if child.children[0].tag == 'StructType' else None + if struct_type: + self.out.write('if (!equal_%s(a.%s, b.%s)) return false;\n' % (struct_type, child.value, child.value)) + else: + self.out.write('if (a.%s !== b.%s) return false;\n' % (child.value, child.value)) self.out.write('return true;\n') self.out.write('}\n\n') elif ast.tag == 'FunLit': @@ -120,6 +127,12 @@ def compile(self, ast): self.out.write(', ') self.compile(ast.children[1]) self.out.write(')') + elif ast.value == '==' and isinstance(ast.children[0].type, Union): + self.out.write('equal_tagged_value(') + self.compile(ast.children[0]) + self.out.write(', ') + self.compile(ast.children[1]) + self.out.write(')') else: self.out.write('(') self.compile(ast.children[0]) diff --git a/test.sh b/test.sh index d40b040..adbefc0 100755 --- a/test.sh +++ b/test.sh @@ -24,7 +24,7 @@ if [ ! x`command -v gcc` = x ]; then APPLIANCES="$APPLIANCES tests/appliances/castile-c-c.md" fi -#APPLIANCES="tests/appliances/castile-c-c.md" +#APPLIANCES="tests/appliances/castile-c-javascript.md" falderal $APPLIANCES tests/Castile.md RESULT=$?