Оператор 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

@ -241,3 +241,5 @@ def `::`(v1, v2) = string(v1) + string(v2)
println 1 :: 2 :: 3
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.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.ast.Statement;
import com.annimon.ownlang.parser.visitors.AssignValidator;
import com.annimon.ownlang.parser.visitors.FunctionAdder;
import com.annimon.ownlang.parser.visitors.VariablePrinter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -21,7 +20,7 @@ public final class Main {
public static void main(String[] args) throws IOException {
if (args.length == 0) {
run(readFile("program.own"), true, true, true);
run(SourceLoader.readSource("program.own"), true, true, true);
return;
}
@ -47,7 +46,7 @@ public final class Main {
case "-f":
case "--file":
if (i + 1 < args.length) {
input = readFile(args[i + 1]);
input = SourceLoader.readSource(args[i + 1]);
i++;
}
break;
@ -62,10 +61,6 @@ public final class Main {
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) {
final TimeMeasurement measurement = new TimeMeasurement();
measurement.start("Tokenize time");

View File

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

View File

@ -129,6 +129,9 @@ public final class Parser {
if (match(TokenType.USE)) {
return new UseStatement(expression());
}
if (match(TokenType.INCLUDE)) {
return new IncludeStatement(expression());
}
if (match(TokenType.FOR)) {
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,
CASE,
EXTRACT,
INCLUDE,
PLUS, // +
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(FunctionalExpression s);
void visit(IfStatement s);
void visit(IncludeStatement s);
void visit(MapExpression s);
void visit(MatchExpression 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
public void visit(MapExpression s) {
for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) {

View File

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