123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- from visitor import Visitor
- from generic_language_constructs import *
- class JavascriptWriter(CLikeWriterBase):
- def __init__(self, outputter):
- self.out = outputter
- ### VISIT METHODS ###
- def visit_ArrayContains(self, a):
- array = a.getArrayExpression()
- el = a.getElementExpression()
- self.out.extendWrite("(")
- array.accept(self)
- self.out.extendWrite(".indexOf(")
- el.accept(self)
- self.out.extendWrite(") !== -1)")
- def visit_ArrayExpression(self, a):
- elements = a.getElements()
- if len(elements) == 0:
- self.out.extendWrite("new Array()")
- else:
- self.out.extendWrite("[")
- self.writeCommaSeparated(elements)
- self.out.extendWrite("]")
- def visit_ArrayIndexOf(self, a):
- array = a.getArrayExpression()
- el = a.getElementExpression()
- array.accept(self)
- self.out.extendWrite(".indexOf(")
- el.accept(self)
- self.out.extendWrite(")")
- def visit_ArrayLength(self, a):
- a.getArrayExpression().accept(self)
- self.out.extendWrite(".length")
- def visit_ArrayPushBack(self, a):
- array = a.getArrayExpression()
- el = a.getElementExpression()
- array.accept(self)
- self.out.extendWrite(".push(")
- el.accept(self)
- self.out.extendWrite(")")
- def visit_AST(self, ast):
- self.writeAll(ast.getEntries())
- def visit_Class(self, c):
- class_name = c.getIdentifier()
- constructor = c.getConstructor()
- super_classes = c.getSuperClassIdentifierList()
- description = c.getDescription()
- self.out.write()
- if description:
- self.writeComment(description)
- constructor.accept(self)
- if super_classes:
- self.out.write(class_name + ".prototype = new Object();")
- self.out.write("(function() {")
- self.out.indent()
- for s in super_classes:
- # workaround for multiple inheritance
- self.out.write("var proto = new " + s + "();")
- self.out.write("for (prop in proto) {")
- self.out.indent()
- self.out.write(class_name + ".prototype[prop] = proto[prop];")
- self.out.dedent()
- self.out.write("}")
- self.out.dedent()
- self.out.write("})();")
- self.writeAll(c.getMembers())
- def visit_Constructor(self, constructor):
- class_name = constructor.getClass().getIdentifier()
- parameters = constructor.getFormalParameters()
- body = constructor.getBody()
- self.out.write("var " + class_name + " = function")
- parameters.accept(self)
- body.accept(self)
- self.out.extendWrite(";")
- def visit_EqualsOperator(self, e):
- self.out.extendWrite(" === ")
- def visit_ForLoopBody(self, body):
- for_loop = body.getForLoop()
- collection_expr = for_loop.getCollectionExpression()
- iterator_identifier = for_loop.getIteratorIdentifier()
- self.out.extendWrite(" {")
- self.out.indent()
- self.out.write("if (!")
- collection_expr.accept(self)
- self.out.extendWrite(".hasOwnProperty(" + iterator_identifier + ")) continue;")
- self.writeAll(body.getEntries())
- self.out.dedent()
- self.out.write("}")
- def visit_ForLoopCurrentElement(self, el):
- collection = el.getCollectionExpression()
- iterator = el.getIteratorIdentifier()
- collection.accept(self)
- self.out.extendWrite("["+iterator+"]")
- def visit_ForLoopIterateArray(self, loop):
- collection = loop.getCollectionExpression()
- iterator = loop.getIteratorIdentifier()
- body = loop.getBody()
- self.out.write("for (var " + iterator + " in ")
- collection.accept(self)
- self.out.extendWrite(")")
- body.accept(self)
- def visit_ForLoopIterateMapValues(self, loop):
- collection = loop.getCollectionExpression()
- iterator = loop.getIteratorIdentifier()
- body = loop.getBody()
- self.out.write("for (var " + iterator + " in ")
- collection.accept(self)
- self.out.extendWrite(")")
- body.accept(self)
- def visit_FormalParameter(self, parameter):
- self.out.extendWrite(parameter.getIdentifier())
- def visit_IncludeStatement(self, i):
- pass # javascript doesn't have an include mechanism
- def visit_LocalVariableDeclaration(self, decl):
- identifier = decl.getIdentifier()
- init_value = decl.getInitValue()
- self.out.extendWrite("var " + identifier)
- if init_value:
- self.out.extendWrite(" = ")
- init_value.accept(self)
- def visit_LogStatement(self, l):
- self.out.write("console.log(\"" + l.getMessage() + "\");")
- def visit_MapExpression(self, m):
- elements = m.getElements()
- if len(elements) == 0:
- self.out.extendWrite("new Object()")
- else:
- self.out.extendWrite("{")
- keys = elements.keys()
- for i in range(len(keys)):
- if i != 0:
- self.out.extendWrite(", ")
- self.out.extendWrite(keys[i] + " : ")
- self.out.extendWrite(" : ")
- elements[keys[i]].accept(self)
- self.out.extendWrite("}")
- def visit_MapIndexedExpression(self, i):
- m = i.getMapExpression()
- key = i.getKeyExpression()
- m.accept(self)
- self.out.extendWrite("[")
- key.accept(self)
- self.out.extendWrite("]")
- def visit_MapRemoveElement(self, stmt):
- map_expr = stmt.getMapExpression()
- key_expr = stmt.getKeyExpression()
- self.out.write("delete ") # this is a statement, not an expression
- map_expr.accept(self)
- self.out.extendWrite("[")
- key_expr.accept(self)
- self.out.extendWrite("];")
- def visit_Method(self, method):
- class_name = method.getClass().getIdentifier()
- method_name = method.getIdentifier()
- description = method.getDescription()
- body = method.getBody()
- parameters = method.getFormalParameters()
- self.out.write()
- if description:
- self.writeComment(description)
- self.writeDescription(method)
- self.out.write(class_name + ".prototype." + method_name + " = function")
- parameters.accept(self)
- body.accept(self)
- self.out.extendWrite(";")
- def visit_MethodBody(self, body):
- method = body.getMethod()
- formal_parameters = method.getFormalParameters()
- formal_parameter_list = formal_parameters.getParameterList()
- self.out.extendWrite(" {")
- self.out.indent()
- # check for undefined parameters and replace them with default values
- for p in formal_parameter_list:
- p_id = p.getIdentifier()
- p_default = p.getDefaultValue()
- if p_default:
- self.out.write("if (" + p_id + " === undefined) " + p_id + " = ")
- p_default.accept(self)
- self.out.extendWrite(";")
- self.writeAll(body.getEntries())
- self.out.dedent()
- self.out.write("}")
- def visit_NoneExpression(self, n):
- self.out.extendWrite("null")
- def visit_Package(self, package):
- name = package.getIdentifier()
- description = package.getDescription()
- self.writeComment("package \"" + name + "\"")
- if description:
- self.writeComment(description)
- self.out.write("var " + name + " = {};")
- self.out.write("(function() {")
- for d in package.getDeclarations():
- d_id = d.getIdentifier()
- d.accept(self)
- self.out.write()
- self.out.write("// add symbol '" + d_id + "' to package '" + name + "'")
- self.out.write(name + "." + d_id + " = " + d_id + ";")
- self.out.write("})();")
- def visit_RuntimeModuleIdentifier(self, r):
- self.out.extendWrite("javascript_runtime")
- def visit_StaticAttribute(self, attr):
- name = attr.getIdentifier()
- init_value = attr.getInitValue()
- class_name = attr.getClass().getIdentifier()
- if init_value:
- self.out.write(class_name + ".prototype." + name + " = ")
- init_value.accept(self)
- self.out.extendWrite(";")
- else:
- self.out.write(class_name + ".prototype." + name + " = null;")
- def visit_SuperClassConstructorCall(self, call):
- super_class = call.getSuperClassIdentifier()
- params = call.getActualParameters()
- param_list = [Literal("this")] + params.getParameterList()
- params = ActualParameters(param_list)
- self.out.extendWrite(super_class)
- self.out.extendWrite(".call")
- params.accept(self)
- def visit_SuperClassDestructorCall(self, call):
- pass # Javascript doesn't have destructors
- def visit_SuperClassMethodCall(self, call):
- super_class = call.getSuperClassIdentifier()
- method_name = call.getMethodIdentifier()
- params = call.getActualParameters()
- param_list = [Literal("this")] + params.getParameterList()
- params = ActualParameters(param_list)
- self.out.extendWrite(super_class)
- self.out.extendWrite(".prototype." + method_name + ".call")
- params.accept(self)
- def visit_ThrowExceptionStatement(self, stmt):
- self.out.write("throw new Error(")
- stmt.getExpression().accept(self)
- self.out.extendWrite(");")
|