Skip to content

Commit

Permalink
Deep struct equality, and union equality, in JavaScript backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
cpressey committed Feb 13, 2022
1 parent b7c71eb commit 605081b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
2 changes: 0 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 16 additions & 3 deletions src/castile/backends/javascript.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from castile.types import Struct
from castile.types import Struct, Union

OPS = {
'and': '&&',
Expand Down Expand Up @@ -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)
Expand All @@ -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':
Expand Down Expand Up @@ -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])
Expand Down
2 changes: 1 addition & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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=$?
Expand Down

0 comments on commit 605081b

Please sign in to comment.