Skip to content

Commit

Permalink
Fix bugs and update to lang version 0.1.0-beta.4
Browse files Browse the repository at this point in the history
  • Loading branch information
ArkinSolomon committed Jan 30, 2023
1 parent b96ac99 commit 5d18d33
Show file tree
Hide file tree
Showing 23 changed files with 220 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Sakura Interpreter -- Java

<img src="https://img.shields.io/badge/Interpreter%20Version-1.0.4-red" /> <img src="https://img.shields.io/badge/Lang Version-0.1.0--beta.2-green" /> [![Tests](https://github.com/ArkinSolomon/sakura-interpreter-java/actions/workflows/test-all.yml/badge.svg)](https://github.com/ArkinSolomon/sakura-interpreter-java/actions/workflows/test-all.yml) [![javadoc](https://javadoc.io/badge2/net.arkinsolomon/sakurainterpreter/javadoc.svg)](https://javadoc.io/doc/net.arkinsolomon/sakurainterpreter)
<img src="https://img.shields.io/badge/Interpreter%20Version-1.1.0-red" /> <img src="https://img.shields.io/badge/Lang Version-0.1.0--beta.4-green" /> [![Tests](https://github.com/ArkinSolomon/sakura-interpreter-java/actions/workflows/test-all.yml/badge.svg)](https://github.com/ArkinSolomon/sakura-interpreter-java/actions/workflows/test-all.yml) [![javadoc](https://javadoc.io/badge2/net.arkinsolomon/sakurainterpreter/javadoc.svg)](https://javadoc.io/doc/net.arkinsolomon/sakurainterpreter)

Sakura Interpreter written in Java.

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>net.arkinsolomon</groupId>
<artifactId>sakurainterpreter</artifactId>
<version>1.0.4</version>
<version>1.1.0</version>
<packaging>jar</packaging>

<name>Sakura Interpreter</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
*/
public class SakuraInterpreter {

public static final String LANG_VERSION = "0.1.0-beta-2";
public static final String INTERPRETER_VERSION = "1.0.4";
public static final String LANG_VERSION = "0.1.0-beta-4";
public static final String INTERPRETER_VERSION = "1.1.0";

private final InterpreterOptions options;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@

import net.arkinsolomon.sakurainterpreter.SakuraInterpreter;
import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.functions.CanReadFunction;
import net.arkinsolomon.sakurainterpreter.functions.CanWriteFunction;
import net.arkinsolomon.sakurainterpreter.functions.ListFunction;
import net.arkinsolomon.sakurainterpreter.functions.RangeFunction;
import net.arkinsolomon.sakurainterpreter.functions.StrFunction;
import net.arkinsolomon.sakurainterpreter.functions.TypeFunction;
import net.arkinsolomon.sakurainterpreter.operations.FileTracker;
import net.arkinsolomon.sakurainterpreter.operations.OperationConfig;
Expand Down Expand Up @@ -207,7 +210,7 @@ public Value executeFunc(String identifier, List<Value> args) {

try {
Function func = (Function) functionValue.value();
return func.execute(args);
return func.execute(args, this);
} catch (SakuraException e) {
throw e;
} catch (Exception e) {
Expand Down Expand Up @@ -253,6 +256,9 @@ private void assignDefaults() {
registerFunc("exit", new ExitFunction());
registerFunc("list", new ListFunction());
registerFunc("type", new TypeFunction());
registerFunc("str", new StrFunction());
registerFunc("canWrite", new CanWriteFunction());
registerFunc("canRead", new CanReadFunction());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 Arkin Solomon.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied limitations under the License.
*/

package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.io.File;
import java.util.List;

/**
* Function to check if read permissions are enabled for a file.
*/
public final class CanReadFunction implements Function {

@Override
public Value execute(List<Value> args, ExecutionContext ctx) {
if (args.size() == 0)
throw new SakuraException("The \"canRead()\" requires one parameter.");
else if (args.get(0).type() != DataType.PATH)
throw new SakuraException("The first parameter to \"canRead()\" needs to be of type path.");

File checkFile = (File) args.get(0).value();

boolean canRead = ctx.getOperationConfig().isValidReadPath(checkFile);
return new Value(DataType.BOOLEAN, canRead, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 Arkin Solomon.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied limitations under the License.
*/

package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.io.File;
import java.util.List;

/**
* Function to check if write permissions are enabled for a file.
*/
public final class CanWriteFunction implements Function {

@Override
public Value execute(List<Value> args, ExecutionContext ctx) {
if (args.size() == 0)
throw new SakuraException("The \"canWrite()\" requires one parameter.");
else if (args.get(0).type() != DataType.PATH)
throw new SakuraException("The first parameter to \"canWrite()\" needs to be of type path.");

File checkFile = (File) args.get(0).value();

boolean canWrite = ctx.getOperationConfig().isValidWritePath(checkFile);
return new Value(DataType.BOOLEAN, canWrite, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 Arkin Solomon.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied limitations under the License.
*/

package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;

/**
* This class should be extended by the executor in order to add a custom function to the interpreter.
*/
public abstract class CustomFunction implements Function {

/**
* Hide execution context from executor.
*
* @param args The values of the arguments passed to the function.
* @return The return value of the function, or {@link Value#NULL} if there is none.
*/
public abstract Value execute(List<Value> args);

@Override
public final Value execute(List<Value> args, ExecutionContext ctx) {
return execute(args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import net.arkinsolomon.sakurainterpreter.exceptions.ExitException;
import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;
Expand All @@ -31,7 +32,7 @@ public final class ExitFunction implements Function {
* Throw an exception that terminates execution.
*/
@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
String reason = "<unknown reason>";
Value retVal = Value.NULL;
byte code = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@

package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;

/**
* Implement this interface to pass functions into the execution context.
* This interface provides a basis for functions to execute. Note that this interface should not be implemented by executors, and is for internal use only. Access to the execution context is not supported. Extend the abstract class {@link CustomFunction} instead for executors.
*/
public interface Function {

/**
* Execute a function.
*
* @param args The argument values.
* @param ctx The execution context of the function.
* @return The result of the function.
*/
Value execute(List<Value> args);
Value execute(List<Value> args, ExecutionContext ctx);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.ListIterable;
import net.arkinsolomon.sakurainterpreter.execution.Value;

Expand All @@ -24,7 +25,7 @@
public final class ListFunction implements Function{

@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
return new Value(DataType.ITERABLE, new ListIterable(args), false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package net.arkinsolomon.sakurainterpreter.functions;

import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;
Expand All @@ -31,7 +32,7 @@ public final class PrintFunction implements Function {
* @return Always returns {@link Value#NULL}.
*/
@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
String[] values = new String[args.size()];
for (int i = 0; i < args.size(); i++) {
Value arg = args.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.RangeIterable;
import net.arkinsolomon.sakurainterpreter.execution.Value;

Expand All @@ -34,7 +35,7 @@ public final class RangeFunction implements Function {
* @return The result of the function.
*/
@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
if (args.size() == 0)
throw new SakuraException("Range function requires at least one argument.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;
Expand All @@ -26,7 +27,7 @@
public final class StrFunction implements Function {

@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
if (args.size() == 0)
throw new SakuraException("Str function requires at least one argument");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import net.arkinsolomon.sakurainterpreter.exceptions.SakuraException;
import net.arkinsolomon.sakurainterpreter.execution.DataType;
import net.arkinsolomon.sakurainterpreter.execution.ExecutionContext;
import net.arkinsolomon.sakurainterpreter.execution.Value;

import java.util.List;
Expand All @@ -27,7 +28,7 @@
public final class TypeFunction implements Function {

@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
if (args.size() == 0)
throw new SakuraException("Type function requires at-least one argument.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ else if (thisChar == '.') {
if (thisToken.isOfType(TokenType.EOF))
break;
else if (thisToken.isOfType(TokenType.PERIOD)) {
if (tokens.size() < i + 2)
if (tokens.size() <= i + 2)
continue;
Token next = tokens.get(i + 1);
Token after = tokens.get(i + 2);
Expand Down Expand Up @@ -880,8 +880,10 @@ else if (!token.isOfType(TokenType.SLASH)) {

if (last.isOfType(TokenType.PATH_LITERAL))
path.set(path.size() - 1, new Token(TokenType.PATH_LITERAL, last.line(), last.column(), last.value() + (String) token.value()));
else
path.add(new Token(TokenType.PATH_LITERAL, token.line(), token.column(), token.value()));

// Continue without adding the token
// The path is not complete
token = tokenStorage.consume();
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void updateRestrictions(Set<File> allowRead, Set<File> disallowRead, Set<
* @return True if {@code directory} is an ancestor of {@code testFile}.
*/
private static boolean isWithinDirectory(File testFile, File directory) {
return Operation.getFilePathStr(testFile).startsWith(Operation.getFilePathStr(directory) + File.separator);
return Operation.getFilePathStr(testFile).startsWith(Operation.getFilePathStr(directory) + File.separator) || Operation.getFilePathStr(testFile).equals(Operation.getFilePathStr(directory));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void register(ExecutionContext ctx) {
}

@Override
public Value execute(List<Value> args) {
public Value execute(List<Value> args, ExecutionContext ctx) {
ExecutionContext tempCtx = new ExecutionContext(rootCtx);

@SuppressWarnings("ConstantConditions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,15 @@ else if (childPath.contains("\n"))
else
path = new File(Operation.getFilePathStr(path), String.valueOf(childPath));
} else
throw new RuntimeException("Path parts must be strings or paths");
throw new SakuraException(token, "Path parts must be strings or paths.");
hasParsedFirstPart = true;
}
return new Value(DataType.PATH, path, false);

if (path == null)
throw new SakuraException(token, "Path can not be empty.");

// Ensure that the path is normalized which gets rid of the '..'s and '.'s
return new Value(DataType.PATH, path.toPath().normalize().toFile(), false);
}

@Override
Expand Down
Loading

0 comments on commit 5d18d33

Please sign in to comment.