# HG changeset patch # User Michael Van De Vanter # Date 1406935822 25200 # Node ID 0fc43b066eee9093ac2306839ca3ca0818a0dc99 # Parent 70f47dbbcabdc2a4ffed6ceec87ef4651056a828 SL/SourceAttribution: correct some omissions, and in particular add new node SLParenExpressionNode to represent a parenthesized expression; this is semantically neutral of course, but needed to account correctly for the text of such an expression (as opposed to its contents). diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Fri Aug 01 16:30:22 2014 -0700 @@ -43,7 +43,7 @@ public final class SLTestRunner extends ParentRunner { - private static final int REPEATS = 10; + private static final int REPEATS = 1; private static final String SOURCE_SUFFIX = ".sl"; private static final String INPUT_SUFFIX = ".input"; @@ -156,7 +156,7 @@ try { SLContext context = new SLContext(new BufferedReader(new StringReader(repeat(testCase.testInput, REPEATS))), printer); final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName); - SLMain.run(context, source, null, REPEATS); + SLMain.run(context, source, System.out, REPEATS); String actualOutput = new String(out.toByteArray()); Assert.assertEquals(repeat(testCase.expectedOutput, REPEATS), actualOutput); diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output Fri Aug 01 16:30:22 2014 -0700 @@ -1,1 +1,1 @@ -Type error at TypeError04.sl line 2 col 4: operation "||" not defined for Boolean false, Number 4 +Type error at TypeError04.sl line 2 col 3: operation "||" not defined for Boolean false, Number 4 diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java Fri Aug 01 16:30:22 2014 -0700 @@ -153,6 +153,9 @@ sourceCallback.startLoading(source); } Parser.parseSL(context, source, null); + System.out.println(source.getName() + "========================"); + System.out.println(source.getCode()); + System.out.println(source.getName() + "========================"); if (sourceCallback != null) { sourceCallback.endLoading(source); } @@ -165,7 +168,7 @@ /* Change to true if you want to see the AST on the console. */ boolean printASTToLog = false; /* Change to true if you want to see source attribution for the AST to the console */ - boolean printSourceAttributionToLog = false; + boolean printSourceAttributionToLog = true; /* Change to dump the AST to IGV over the network. */ boolean dumpASTToIGV = false; @@ -192,6 +195,7 @@ } finally { printScript("after execution", context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV); } + return; } /** diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLParenExpressionNode.java Fri Aug 01 16:30:22 2014 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.sl.nodes.expression; + +import java.math.*; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; +import com.oracle.truffle.sl.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * A {@link SLExpressionNode} that represents a parenthesized expression; it simply returns the + * value of the enclosed (child) expression. It is represented separately in the AST for the purpose + * of correct source attribution; this preserves the lexical relationship between the two + * parentheses and allows a tool to describe the expression as distinct from its contents. + */ +@NodeInfo(description = "A parenthesized expression") +public class SLParenExpressionNode extends SLExpressionNode { + + private final SLExpressionNode expression; + + public SLParenExpressionNode(SourceSection src, SLExpressionNode expression) { + super(src); + this.expression = insert(expression); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + return expression.executeGeneric(frame); + } + + @Override + public long executeLong(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeLong(frame); + } + + @Override + public BigInteger executeBigInteger(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeBigInteger(frame); + } + + @Override + public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeBoolean(frame); + } + + @Override + public String executeString(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeString(frame); + } + + @Override + public SLFunction executeFunction(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeFunction(frame); + } + + @Override + public SLNull executeNull(VirtualFrame frame) throws UnexpectedResultException { + return expression.executeNull(frame); + } +} diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Fri Aug 01 16:30:22 2014 -0700 @@ -53,7 +53,7 @@ public final Scanner scanner; public final Errors errors; private final SLNodeFactory factory; - + public Parser(SLContext context, Source source, SLNodeProber astProber) { this.scanner = new Scanner(source.getInputStream()); this.factory = new SLNodeFactory(context, source, astProber); @@ -134,41 +134,41 @@ void Function() { Expect(4); Expect(1); - factory.startFunction(t); + factory.startFunction(t); Expect(5); if (la.kind == 1) { Get(); - factory.addFormalParameter(t); + factory.addFormalParameter(t); while (la.kind == 6) { Get(); Expect(1); - factory.addFormalParameter(t); + factory.addFormalParameter(t); } } Expect(7); SLStatementNode body = Block(false); - factory.finishFunction(body); + factory.finishFunction(body); } SLStatementNode Block(boolean inLoop) { SLStatementNode result; factory.startBlock(); - List body = new ArrayList<>(); + List body = new ArrayList<>(); Expect(8); - int lBracePos = t.charPos; + int start = t.charPos; while (StartOf(1)) { SLStatementNode s = Statement(inLoop); - body.add(s); + body.add(s); } Expect(9); - int length = (t.charPos + t.val.length()) - lBracePos; - result = factory.finishBlock(body, lBracePos, length); + int length = (t.charPos + t.val.length()) - start; + result = factory.finishBlock(body, start, length); return result; } SLStatementNode Statement(boolean inLoop) { SLStatementNode result; - result = null; + result = null; switch (la.kind) { case 13: { result = WhileStatement(); @@ -176,13 +176,13 @@ } case 10: { Get(); - if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } + if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } Expect(11); break; } case 12: { Get(); - if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } + if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } Expect(11); break; } @@ -207,12 +207,12 @@ SLStatementNode WhileStatement() { SLStatementNode result; Expect(13); + Token whileToken = t; Expect(5); - Token whileToken = t; SLExpressionNode condition = Expression(); Expect(7); SLStatementNode body = Block(true); - result = factory.createWhile(whileToken, condition, body); + result = factory.createWhile(whileToken, condition, body); return result; } @@ -220,16 +220,16 @@ SLStatementNode result; Expect(14); Expect(5); - Token ifToken = t; + Token ifToken = t; SLExpressionNode condition = Expression(); Expect(7); SLStatementNode thenPart = Block(inLoop); - SLStatementNode elsePart = null; + SLStatementNode elsePart = null; if (la.kind == 15) { Get(); elsePart = Block(inLoop); } - result = factory.createIf(ifToken, condition, thenPart, elsePart); + result = factory.createIf(ifToken, condition, thenPart, elsePart); return result; } @@ -237,11 +237,11 @@ SLStatementNode result; Expect(16); Token returnToken = t; - SLExpressionNode value = null; + SLExpressionNode value = null; if (StartOf(2)) { value = Expression(); } - result = factory.createReturn(returnToken, value); + result = factory.createReturn(returnToken, value); Expect(11); return result; } @@ -251,9 +251,9 @@ result = LogicTerm(); while (la.kind == 17) { Get(); - Token op = t; + Token op = t; SLExpressionNode right = LogicTerm(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -263,9 +263,9 @@ result = LogicFactor(); while (la.kind == 18) { Get(); - Token op = t; + Token op = t; SLExpressionNode right = LogicFactor(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -300,9 +300,9 @@ break; } } - Token op = t; + Token op = t; SLExpressionNode right = Arithmetic(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -316,9 +316,9 @@ } else { Get(); } - Token op = t; + Token op = t; SLExpressionNode right = Term(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -332,52 +332,56 @@ } else { Get(); } - Token op = t; + Token op = t; SLExpressionNode right = Factor(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } SLExpressionNode Factor() { SLExpressionNode result; - result = null; + result = null; if (la.kind == 1) { Get(); - Token nameToken = t; + Token nameToken = t; if (la.kind == 5) { Get(); List parameters = new ArrayList<>(); - SLExpressionNode parameter; + SLExpressionNode parameter; if (StartOf(2)) { parameter = Expression(); - parameters.add(parameter); + parameters.add(parameter); while (la.kind == 6) { Get(); parameter = Expression(); - parameters.add(parameter); + parameters.add(parameter); } } Expect(7); - Token finalToken = t; - result = factory.createCall(nameToken, parameters, finalToken); + Token finalToken = t; + result = factory.createCall(nameToken, parameters, finalToken); } else if (la.kind == 29) { Get(); SLExpressionNode value = Expression(); - result = factory.createAssignment(nameToken, value); + result = factory.createAssignment(nameToken, value); } else if (StartOf(4)) { - result = factory.createRead(nameToken); + result = factory.createRead(nameToken); } else SynErr(32); } else if (la.kind == 2) { Get(); - result = factory.createStringLiteral(t); + result = factory.createStringLiteral(t); } else if (la.kind == 3) { Get(); - result = factory.createNumericLiteral(t); + result = factory.createNumericLiteral(t); } else if (la.kind == 5) { Get(); + int start = t.charPos; result = Expression(); + SLExpressionNode expr = result; Expect(7); + int length = (t.charPos + t.val.length()) - start; + result = factory.createParenExpression(expr, start, length); } else SynErr(33); return result; } diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java Fri Aug 01 16:30:22 2014 -0700 @@ -99,7 +99,7 @@ * ensures that accesses to parameters are specialized the same way as local variables are * specialized. */ - final SourceSection src = source.createSection(nameToken.val, nameToken.charPos, nameToken.val.length()); + final SourceSection src = srcFromToken(nameToken); SLReadArgumentNode readArg = new SLReadArgumentNode(src, parameterCount); methodNodes.add(createAssignment(nameToken, readArg)); parameterCount++; @@ -166,22 +166,22 @@ } } - public SLStatementNode createBreak(Token t) { - return new SLBreakNode(source.createSection(t.val, t.charPos, t.val.length())); + public SLStatementNode createBreak(Token breakToken) { + return new SLBreakNode(srcFromToken(breakToken)); } - public SLStatementNode createContinue(Token t) { - return new SLContinueNode(source.createSection(t.val, t.charPos, t.val.length())); + public SLStatementNode createContinue(Token continueToken) { + return new SLContinueNode(srcFromToken(continueToken)); } - public SLStatementNode createWhile(Token t, SLExpressionNode conditionNode, SLStatementNode bodyNode) { - final int start = t.charPos; + public SLStatementNode createWhile(Token whileToken, SLExpressionNode conditionNode, SLStatementNode bodyNode) { + final int start = whileToken.charPos; final int end = bodyNode.getSourceSection().getCharEndIndex(); - return new SLWhileNode(source.createSection(t.val, start, end - start), conditionNode, bodyNode); + return new SLWhileNode(source.createSection(whileToken.val, start, end - start), conditionNode, bodyNode); } - public SLStatementNode createIf(Token t, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { - final int start = t.charPos; + public SLStatementNode createIf(Token ifToken, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { + final int start = ifToken.charPos; final int end = elsePartNode == null ? thenPartNode.getSourceSection().getCharEndIndex() : elsePartNode.getSourceSection().getCharEndIndex(); // if (prober != null) { @@ -191,7 +191,7 @@ // wrappedThenNode, elsePartNode); // } - return new SLIfNode(source.createSection(t.val, start, end - start), conditionNode, thenPartNode, elsePartNode); + return new SLIfNode(source.createSection(ifToken.val, start, end - start), conditionNode, thenPartNode, elsePartNode); } public SLStatementNode createReturn(Token t, SLExpressionNode valueNode) { @@ -260,7 +260,7 @@ public SLExpressionNode createRead(Token nameToken) { final FrameSlot frameSlot = lexicalScope.locals.get(nameToken.val); - final SourceSection src = source.createSection(nameToken.val, nameToken.charPos, nameToken.val.length()); + final SourceSection src = srcFromToken(nameToken); if (frameSlot != null) { /* Read of a local variable. */ return SLReadLocalVariableNodeFactory.create(src, frameSlot); @@ -274,14 +274,14 @@ /* Remove the trailing and ending " */ String literal = literalToken.val; assert literal.length() >= 2 && literal.startsWith("\"") && literal.endsWith("\""); - final SourceSection src = source.createSection(literalToken.val, literalToken.charPos, literalToken.val.length()); + final SourceSection src = srcFromToken(literalToken); literal = literal.substring(1, literal.length() - 1); return new SLStringLiteralNode(src, literal); } public SLExpressionNode createNumericLiteral(Token literalToken) { - final SourceSection src = source.createSection(literalToken.val, literalToken.charPos, literalToken.val.length()); + final SourceSection src = srcFromToken(literalToken); try { /* Try if the literal is small enough to fit into a long value. */ return new SLLongLiteralNode(src, Long.parseLong(literalToken.val)); @@ -291,4 +291,16 @@ } } + public SLExpressionNode createParenExpression(SLExpressionNode expressionNode, int start, int length) { + final SourceSection src = source.createSection("()", start, length); + return new SLParenExpressionNode(src, expressionNode); + } + + /** + * Creates source description of a single token. + */ + private SourceSection srcFromToken(Token token) { + return source.createSection(token.val, token.charPos, token.val.length()); + } + } diff -r 70f47dbbcabd -r 0fc43b066eee graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Fri Aug 01 16:28:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Fri Aug 01 16:30:22 2014 -0700 @@ -84,12 +84,12 @@ Block = (. factory.startBlock(); List body = new ArrayList<>(); .) -"{" (. int lBracePos = t.charPos; .) +"{" (. int start = t.charPos; .) { Statement (. body.add(s); .) } -"}" (. int length = (t.charPos + t.val.length()) - lBracePos; .) - (. result = factory.finishBlock(body, lBracePos, length); .) +"}" (. int length = (t.charPos + t.val.length()) - start; .) + (. result = factory.finishBlock(body, start, length); .) . @@ -115,8 +115,8 @@ WhileStatement = -"while" -"(" (. Token whileToken = t; .) +"while" (. Token whileToken = t; .) +"(" Expression ")" Block (. result = factory.createWhile(whileToken, condition, body); .) @@ -225,7 +225,10 @@ | numericLiteral (. result = factory.createNumericLiteral(t); .) | - "(" Expression ")" + "(" (. int start = t.charPos; .) + Expression (. SLExpressionNode expr = result; .) + ")" (. int length = (t.charPos + t.val.length()) - start; .) + (. result = factory.createParenExpression(expr, start, length); .) ) .