Оператор include

This commit is contained in:
Victor 2016-02-19 12:20:20 +02:00
parent 3e16e49ce7
commit 8eb25ef8c8
10 changed files with 96 additions and 11 deletions

View File

@ -240,4 +240,6 @@ println `extended word variable`
def `::`(v1, v2) = string(v1) + string(v2) def `::`(v1, v2) = string(v1) + string(v2)
println 1 :: 2 :: 3 println 1 :: 2 :: 3
println "\u042a" println "\u042a"
include "visitor.own"

View File

@ -3,14 +3,13 @@ package com.annimon.ownlang;
import com.annimon.ownlang.lib.CallStack; import com.annimon.ownlang.lib.CallStack;
import com.annimon.ownlang.parser.Lexer; import com.annimon.ownlang.parser.Lexer;
import com.annimon.ownlang.parser.Parser; import com.annimon.ownlang.parser.Parser;
import com.annimon.ownlang.parser.SourceLoader;
import com.annimon.ownlang.parser.Token; import com.annimon.ownlang.parser.Token;
import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.visitors.AssignValidator; import com.annimon.ownlang.parser.visitors.AssignValidator;
import com.annimon.ownlang.parser.visitors.FunctionAdder; import com.annimon.ownlang.parser.visitors.FunctionAdder;
import com.annimon.ownlang.parser.visitors.VariablePrinter; import com.annimon.ownlang.parser.visitors.VariablePrinter;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -21,7 +20,7 @@ public final class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if (args.length == 0) { if (args.length == 0) {
run(readFile("program.own"), true, true, true); run(SourceLoader.readSource("program.own"), true, true, true);
return; return;
} }
@ -47,7 +46,7 @@ public final class Main {
case "-f": case "-f":
case "--file": case "--file":
if (i + 1 < args.length) { if (i + 1 < args.length) {
input = readFile(args[i + 1]); input = SourceLoader.readSource(args[i + 1]);
i++; i++;
} }
break; break;
@ -62,10 +61,6 @@ public final class Main {
run(input, showTokens, showAst, showMeasurements); run(input, showTokens, showAst, showMeasurements);
} }
private static String readFile(String file) throws IOException {
return new String( Files.readAllBytes(Paths.get(file)), "UTF-8");
}
private static void run(String input, boolean showTokens, boolean showAst, boolean showMeasurements) { private static void run(String input, boolean showTokens, boolean showAst, boolean showMeasurements) {
final TimeMeasurement measurement = new TimeMeasurement(); final TimeMeasurement measurement = new TimeMeasurement();
measurement.start("Tokenize time"); measurement.start("Tokenize time");

View File

@ -91,6 +91,7 @@ public final class Lexer {
KEYWORDS.put("match", TokenType.MATCH); KEYWORDS.put("match", TokenType.MATCH);
KEYWORDS.put("case", TokenType.CASE); KEYWORDS.put("case", TokenType.CASE);
KEYWORDS.put("extract", TokenType.EXTRACT); KEYWORDS.put("extract", TokenType.EXTRACT);
KEYWORDS.put("include", TokenType.INCLUDE);
} }
private final String input; private final String input;

View File

@ -129,6 +129,9 @@ public final class Parser {
if (match(TokenType.USE)) { if (match(TokenType.USE)) {
return new UseStatement(expression()); return new UseStatement(expression());
} }
if (match(TokenType.INCLUDE)) {
return new IncludeStatement(expression());
}
if (match(TokenType.FOR)) { if (match(TokenType.FOR)) {
return forStatement(); return forStatement();
} }

View File

@ -0,0 +1,30 @@
package com.annimon.ownlang.parser;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public final class SourceLoader {
public static String readSource(String name) throws IOException {
InputStream is = SourceLoader.class.getResourceAsStream(name);
if (is != null) return readStream(is);
is = new FileInputStream(name);
return readStream(is);
}
private static String readStream(InputStream is) throws IOException {
final StringBuilder text = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
text.append(line);
text.append(System.lineSeparator());
}
}
return text.toString();
}
}

View File

@ -27,6 +27,7 @@ public enum TokenType {
MATCH, MATCH,
CASE, CASE,
EXTRACT, EXTRACT,
INCLUDE,
PLUS, // + PLUS, // +
MINUS, // - MINUS, // -

View File

@ -0,0 +1,47 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.parser.Lexer;
import com.annimon.ownlang.parser.Parser;
import com.annimon.ownlang.parser.SourceLoader;
import com.annimon.ownlang.parser.Token;
import com.annimon.ownlang.parser.visitors.FunctionAdder;
import java.util.List;
/**
*
* @author aNNiMON
*/
public final class IncludeStatement implements Statement {
public final Expression expression;
public IncludeStatement(Expression expression) {
this.expression = expression;
}
@Override
public void execute() {
try {
final String input = SourceLoader.readSource(expression.eval().asString());
final List<Token> tokens = new Lexer(input).tokenize();
final Parser parser = new Parser(tokens);
final Statement program = parser.parse();
if (!parser.getParseErrors().hasErrors()) {
program.accept(new FunctionAdder());
program.execute();
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return "include " + expression;
}
}

View File

@ -24,6 +24,7 @@ public interface Visitor {
void visit(ExprStatement s); void visit(ExprStatement s);
void visit(FunctionalExpression s); void visit(FunctionalExpression s);
void visit(IfStatement s); void visit(IfStatement s);
void visit(IncludeStatement s);
void visit(MapExpression s); void visit(MapExpression s);
void visit(MatchExpression s); void visit(MatchExpression s);
void visit(PrintStatement s); void visit(PrintStatement s);

View File

@ -118,6 +118,11 @@ public abstract class AbstractVisitor implements Visitor {
} }
} }
@Override
public void visit(IncludeStatement s) {
s.expression.accept(this);
}
@Override @Override
public void visit(MapExpression s) { public void visit(MapExpression s) {
for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) { for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) {

View File

@ -1,5 +1,5 @@
func() function()
def func() print "function\n" def function() print "function\n"
a = 2 + 3 * 4 a = 2 + 3 * 4
print a print a