Author: dda
Date: 2008-01-03 08:21:35 -0800 (Thu, 03 Jan 2008)
New Revision: 7713
Added:
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTPassthroughDirective.java
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
Log:
Change 20080102-dda-4 by [EMAIL PROTECTED] on 2008-01-02 15:39:25 EST
in /Users/dda/laszlo/src/svn/openlaszlo/branches/devildog
for http://svn.openlaszlo.org/openlaszlo/branches/devildog
Summary: Added #passthrough directive for SWF9
New Features: #passthrough { ...something... }# will
pass ...something... directly to the SWF9 third party compiler.
This will be useful for adding 'import' statements, special syntax
for including resources, or other special cases.
Bugs Fixed: LPP-5319
Technical Reviewer: ptw (pending)
QA Reviewer: hminsky (pending)
Doc Reviewer: (pending)
Documentation: Uncertain as whether this will be ever needed by LZX users.
If so, see details below for a complete description.
Release Notes:
Details:
The new '#passthrough' statement can appear anywhere an executable statement
can appear (including at the 'top level' for those coding in .lzs). The syntax
of the
passthrough is:
#passthrough (prop1:value, prop2:value, ...) { ...anything... }#
There need not be any properties (e.g. prop1, prop2). If there are none, then
the parentheses are optional.
For SWF9, the only property currently allowed is 'toplevel', which must have a
boolean (true or value) value.
By default, toplevel is false.
The contents of ...anything... can be any text, including anything that might
normally be considered to
violate the grammar. The exact string between the { and }# is copied to the
output file for the current class
verbatim. Even if there is no explicit class, the SWF9 generator emits output
into a default class, currently
named 'DefaultApplication'. The position of the verbatim text appears exactly
where the translation
for the statement at this position would be. The exception is that any
passthrough marked as 'toplevel'
appears 'outside' the class definition, but within the 'package ... {' block.
Although this is chiefly implemented for SWF9, it could in theory be used for
the Javascript runtime
if needed at a future time. It has not been tested for Javascript though.
Implementation:
The implementation is straightforward, with the addition of a
ASTPassthroughDirective, which contains
the text for the passthrough, as well as a set of prop/value pairs (more
general than needed now,
since we only allow 'toplevel'). The only trick in the implementation is the
grammar. The only
feasible way to grab all the text unfettered seemed to be to treat the entire
statement as a single
token. This requires us to explicitly break out the properties (prop1:...) -
but it is straightforward
to call back into the parser to assemble the list of properties.
Tests:
No formal tests included.
So far, some insertions of passthrough statements, both toplevel and not, at
various parse points
(outside class, inside class, inside function) into LzNode.js. Additionally
tried some
erroneous properties and property values to make sure error reports were
meaningful.
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
2008-01-03 16:21:35 UTC (rev 7713)
@@ -1,7 +1,7 @@
/* ****************************************************************************
* Parser.jjt
*
- * Copyright (c) 2002-2007 Laszlo Systems, Inc.
+ * Copyright (c) 2002-2008 Laszlo Systems, Inc.
* All Rights Reserved.
*
* This software is the proprietary information of Laszlo Systems, Inc.
@@ -10,7 +10,7 @@
*
****************************************************************************/
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
-* Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
+* Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* J_LZ_COPYRIGHT_END *********************************************************/
@@ -248,6 +248,19 @@
>
}
+/* passthrough */
+MORE: {
+ "#passthrough" : IN_PASSTHROUGH
+}
+
+<IN_PASSTHROUGH> TOKEN : {
+ <PASSTHROUGH: "}#" > : DEFAULT
+}
+
+<IN_PASSTHROUGH> MORE: {
+ < ~[] >
+}
+
/* identifiers */
TOKEN: {
@@ -315,8 +328,9 @@
| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
}
-void Literal() #Literal : {Token t;}
-{ t = <DECIMAL_LITERAL>
+ASTLiteral Literal() #Literal : {Token t;}
+{
+( t = <DECIMAL_LITERAL>
{jjtThis.setDecimalValue(t.image);}
| t = <OCTAL_LITERAL>
{jjtThis.setOctalValue(t.image);}
@@ -334,6 +348,7 @@
{jjtThis.setNullValue();}
| t = <UNTERMINATED_STRING_LITERAL>
{ throw new ParseException(t, "unterminated string: " +
t.image.substring(0, t.image.length()-1)); }
+) { return jjtThis; }
}
void StringLiteral() #Literal : {Token t;}
@@ -627,6 +642,7 @@
| SwitchStatement()
| ThrowStatement()
| TryStatement()
+ | PassthroughDirective()
}
void Statement() #Statement : {}
@@ -965,6 +981,44 @@
{return jjtThis;}
}
+// #passthrough [ (property1:value1, property2:value2, ...) ] { ... }#
+//
+void PassthroughDirective() #PassthroughDirective : {Token t;}
+{
+ /*
+ * The passthrough contents may contain lots of otherwise recognized
+ * tokens which can confuse the parser if we attempt to collect the
+ * the passthrough directive with properties using 'straightforward'
+ * parsing techniques. Also the presence of '{' as the beginning of
+ * the passthrough text can lead to grammar ambiguities. So, we
+ * collect everything between #passthrough and }# into the PASSTHROUGH
+ * token and reparse the stuff before "{" to get the properties.
+ */
+ t = <PASSTHROUGH>
+ {
+ // skip the #passthrough and }# tokens
+ String raw = t.image.substring("#passthrough".length(),t.image.length()-2);
+ int beginBrace = raw.indexOf('{');
+ if (beginBrace < 0)
+ throw new ParseException("#passthrough property: missing {");
+ jjtThis.setText(raw.substring(beginBrace+1));
+
+ Parser p = new Parser(new java.io.StringReader(raw.substring(0,
beginBrace)));
+ p.PassthroughProperties(jjtThis);
+ }
+}
+
+void PassthroughProperties(ASTPassthroughDirective pt) #void : {}
+{
+ [ "(" [PassthroughProperty(pt) ("," PassthroughProperty(pt))*] ")" ]
+}
+
+void PassthroughProperty(ASTPassthroughDirective pt) : {SimpleNode key;
SimpleNode value;}
+{
+ key = Identifier() ":" value = Literal()
+ { pt.set(key, value); }
+}
+
SimpleNode IfDirective() #IfDirective : { Token t;}
{
"if" "(" Expression() ")" DirectiveBlock()
Added:
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTPassthroughDirective.java
Property changes on:
openlaszlo/branches/devildog/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTPassthroughDirective.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -442,6 +442,9 @@
} else if (directive instanceof ASTPragmaDirective) {
visitPragmaDirective(directive, directive.getChildren());
continue;
+ } else if (directive instanceof ASTPassthroughDirective) {
+ visitPassthroughDirective(directive, directive.getChildren());
+ continue;
}
if ("1".equals(cpass)) {
// Function, class, and top-level expressions are processed in pass 1
@@ -2654,7 +2657,6 @@
}
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
-* Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
+* Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* J_LZ_COPYRIGHT_END *********************************************************/
-
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -321,6 +321,31 @@
return new ASTEmptyExpression(0);
}
+ public void errPassthroughProperty(SimpleNode node, String key, Object
value, String errorType) {
+ throw new ParseException(key + ": " + errorType +
+ " for #passthrough property in " +
+ node.filename + " (" + node.beginLine + ")");
+ }
+
+ public void checkPassthroughProperty(SimpleNode node, String key, Object
value) {
+ // by default, no parameters are allowed
+ // this can be overridden by the various runtime generators
+ errPassthroughProperty(node, key, value, "unknown key");
+ }
+
+ public SimpleNode visitPassthroughDirective(SimpleNode node, SimpleNode[]
children) {
+ // just check parameters here.
+ assert node instanceof ASTPassthroughDirective;
+ Map props = ((ASTPassthroughDirective)node).getProperties();
+ for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
+ String key = (String)iter.next();
+ Object value = props.get(key);
+
+ checkPassthroughProperty(node, key, value);
+ }
+ return node;
+ }
+
// Flatten nested StatementList structures
private List flatten(SimpleNode[] src) {
List dst = new ArrayList();
@@ -464,6 +489,9 @@
}
} else if (n instanceof ASTPragmaDirective) {
visitPragmaDirective(n, n.getChildren());
+ } else if (n instanceof ASTPassthroughDirective) {
+ visitPassthroughDirective(n, n.getChildren());
+ stmts.add(n);
} else {
if (keepClassMethods && mod != null) {
stmts.add(mod);
@@ -537,6 +565,9 @@
if (node instanceof ASTPragmaDirective) {
newNode = visitPragmaDirective(node, children);
}
+ else if (node instanceof ASTPassthroughDirective) {
+ newNode = visitPassthroughDirective(node, children);
+ }
else if (node instanceof ASTClassDefinition) {
newNode = visitClassDefinition(node, children);
}
@@ -941,6 +972,6 @@
}
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
-* Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
+* Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* J_LZ_COPYRIGHT_END *********************************************************/
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -80,15 +80,15 @@
// Map for options
public static class OptionMap extends HashMap {
- OptionMap () {
+ public OptionMap () {
super();
}
- OptionMap (Map m) {
+ public OptionMap (Map m) {
super(m);
}
- OptionMap (List pairs) {
+ public OptionMap (List pairs) {
for (Iterator i = pairs.iterator(); i.hasNext(); ) {
List pair = (List)i.next();
put(pair.get(0), pair.get(1));
@@ -865,6 +865,6 @@
}
/**
- * @copyright Copyright 2001-2007 Laszlo Systems, Inc. All Rights
+ * @copyright Copyright 2001-2008 Laszlo Systems, Inc. All Rights
* Reserved. Use is subject to license terms.
*/
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -282,6 +282,8 @@
newDirective = visitProgram(directive, children, cpass);
} else if (directive instanceof ASTPragmaDirective) {
newDirective = visitPragmaDirective(directive,
directive.getChildren());
+ } else if (directive instanceof ASTPassthroughDirective) {
+ newDirective = visitPassthroughDirective(directive,
directive.getChildren());
} else {
if ("1".equals(cpass)) {
// Function, class, and top-level expressions are processed in pass 1
@@ -1723,7 +1725,7 @@
}
/**
- * @copyright Copyright 2006-2007 Laszlo Systems, Inc. All Rights
+ * @copyright Copyright 2006-2008 Laszlo Systems, Inc. All Rights
* Reserved. Use is subject to license terms.
*/
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -1,7 +1,7 @@
/* -*- mode: Java; c-basic-offset: 2; -*- */
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
-* Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. *
+* Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* J_LZ_COPYRIGHT_END *********************************************************/
@@ -230,6 +230,9 @@
if (node instanceof ASTPragmaDirective) {
return lnum(node, visitPragmaDirective(node, children));
}
+ if (node instanceof ASTPassthroughDirective) {
+ return lnum(node, visitPassthroughDirective(node, children));
+ }
if (node instanceof ASTPostfixExpression) {
return lnum(node, visitPostfixExpression(node, children));
}
@@ -463,6 +466,9 @@
public String visitPragmaDirective(SimpleNode node, String[] children) {
return "#pragma " + children[0];
}
+ public String visitPassthroughDirective(SimpleNode node, String[] children) {
+ return ((ASTPassthroughDirective)node).getText();
+ }
public String visitPostfixExpression(SimpleNode node, String[] children) {
int op = ((ASTOperator)node.get(1)).getOperator();
int thisPrec = prec(op, true);
@@ -836,6 +842,7 @@
}
public static final char ANNOTATE_MARKER = '\u0001';
+ // note: numbers are reserved for annotation to streams
public static final char ANNOTATE_OP_LINENUM = 'L';
public static final char ANNOTATE_OP_CLASSNAME = 'C';
public static final char ANNOTATE_OP_CLASSEND = 'c';
@@ -886,6 +893,13 @@
return sb.toString();
}
+ // The text is directed to a numbered stream. 0 should be avoided,
+ // we may use it as a synonym for the 'default' text stream.
+ public String annotateStream(int streamNum, String str) {
+ assert (streamNum >= 0 && streamNum <= 9);
+ return makeAnnotation((char)('0' + streamNum), str);
+ }
+
/**
* Add annotations, which look like \u0001 opchar operand \u0001
* opchar is a single character.
@@ -957,6 +971,9 @@
case ANNOTATE_OP_NODEEND:
String nodenm = (String)nodestack.removeLast();
return "#endnode " + nodenm;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return "#stream " + op + ": " + operand;
}
return "";
}
@@ -992,6 +1009,11 @@
case ANNOTATE_OP_CLASSEND:
curtu = defaulttu;
return "";
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ int streamNum = ((op) - '0');
+ curtu.addStreamText(streamNum, operand);
+ return "";
}
return "";
}
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -32,6 +32,8 @@
*/
public class SWF9Generator extends JavascriptGenerator {
+ public static final String PASSTHROUGH_TOPLEVEL = "toplevel";
+
// TODO: [2007-12-12 dda] make DEBUG_OUTPUT a compiler option.
/**
* When set, some extra debugging files are saved.
@@ -203,7 +205,21 @@
}
}
+ /**
+ * Override superclass version, we honor some passthrough properties.
+ */
+ public void checkPassthroughProperty(SimpleNode node, String key, Object
value) {
+ if (key.equals(PASSTHROUGH_TOPLEVEL)) {
+ if (!(value instanceof Boolean)) {
+ errPassthroughProperty(node, key, value, "Boolean value expected");
+ }
+ }
+ else {
+ errPassthroughProperty(node, key, value, "unknown key");
+ }
+ }
+
public byte[] getBytes(InputStream is)
throws IOException
{
@@ -698,6 +714,8 @@
public void writeOutputFile(TranslationUnit tunit, String pre, String post) {
String name = tunit.getName();
String body = tunit.getContents();
+ // Everything inserted by #passthrough (toplevel:true) goes into stream 1
+ String toplevel = tunit.getStreamText(1);
String infilename = tempdir + File.separator + name + ".as";
tunit.setSourceFileName(infilename);
@@ -710,6 +728,7 @@
try {
fos = new FileOutputStream(infilename);
fos.write(pre.getBytes());
+ fos.write(toplevel.getBytes());
fos.write(body.getBytes());
fos.write(post.getBytes());
fos.close();
@@ -866,7 +885,7 @@
}
/**
- * @copyright Copyright 2006-2007 Laszlo Systems, Inc. All Rights
+ * @copyright Copyright 2006-2008 Laszlo Systems, Inc. All Rights
* Reserved. Use is subject to license terms.
*/
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -1,7 +1,7 @@
/* -*- mode: Java; c-basic-offset: 2; -*- */
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
-* Copyright 2007 Laszlo Systems, Inc. All Rights Reserved. *
+* Copyright 2007-2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* J_LZ_COPYRIGHT_END *********************************************************/
@@ -140,6 +140,13 @@
public String visitPragmaDirective(SimpleNode node, String[] children) {
return "// (ignored) pragma " + children[0];
}
+ public String visitPassthroughDirective(SimpleNode node, String[] children) {
+ ASTPassthroughDirective passthrough = (ASTPassthroughDirective)node;
+ String text = passthrough.getText();
+ if (passthrough.getBoolean(SWF9Generator.PASSTHROUGH_TOPLEVEL))
+ text = annotateStream(1, text);
+ return text;
+ }
public String visitIdentifier(SimpleNode node, String[] children) {
ASTIdentifier ident = (ASTIdentifier)node;
Modified:
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
===================================================================
---
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
2008-01-03 08:17:44 UTC (rev 7712)
+++
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
2008-01-03 16:21:35 UTC (rev 7713)
@@ -27,6 +27,7 @@
private int linenum = 1;
private String srcFilename; // name of associated source file, if
applicable
private boolean isDefault = false;
+ private Map streams = new HashMap(); // alternate streams, indexed by number
public String getName() {
return name;
@@ -68,6 +69,23 @@
linenum += countOccurence(s, '\n');
}
+ public void addStreamText(int streamNum, String s) {
+ Integer key = new Integer(streamNum);
+ String cur = (String)streams.get(key);
+ if (cur == null)
+ cur = "";
+ cur += s;
+ streams.put(key, cur);
+ }
+
+ public String getStreamText(int streamNum) {
+ Integer key = new Integer(streamNum);
+ String cur = (String)streams.get(key);
+ if (cur == null)
+ cur = "";
+ return cur;
+ }
+
public void setInputLineNumber(int inputLinenum) {
Integer key = new Integer(linenum);
// we want the least value in the mapping
@@ -118,6 +136,6 @@
}
/**
- * @copyright Copyright 2001-2007 Laszlo Systems, Inc. All Rights
+ * @copyright Copyright 2001-2008 Laszlo Systems, Inc. All Rights
* Reserved. Use is subject to license terms.
*/
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins