add helloworldgen.isbpl to demonstrate streams, fix streams

This commit is contained in:
Daniella / Tove 2022-03-06 18:46:04 +01:00
parent e9022405c9
commit 66582125fc
6 changed files with 143 additions and 34 deletions

View file

@ -21,6 +21,7 @@ public class ISBPL {
ArrayList<String> lastWords = new ArrayList<>(16);
int exitCode;
private ISBPLStreamer streamer = new ISBPLStreamer(this);
ArrayList<String> included = new ArrayList<>();
public ISBPL() {
functionStack.push(new HashMap<>());
@ -267,26 +268,32 @@ public class ISBPL {
functionStack.get(functionStack.size() - 1 - ((int) i.object)).get(toJavaString(s)).call(file);
};
break;
case "reload":
func = (File file) -> {
String filepath = getFilePathForInclude((Stack<ISBPLObject>) stack, file);
if(included.contains(filepath)) {
File f = new File(filepath).getAbsoluteFile();
try {
interpret(f, readFile(f), stack);
}
catch (IOException e) {
throw new ISBPLError("IO", "Couldn't find file " + filepath + " required by include keyword.");
}
}
};
break;
case "include":
func = (File file) -> {
ISBPLObject s = stack.pop();
String filepath = toJavaString(s);
processPath:
{
if (filepath.startsWith("/"))
break processPath;
if (filepath.startsWith("#")) {
filepath = System.getenv().getOrDefault("ISBPL_PATH", "/usr/lib/isbpl") + "/" + filepath.substring(1);
break processPath;
String filepath = getFilePathForInclude((Stack<ISBPLObject>) stack, file);
if(!included.contains(filepath)) {
File f = new File(filepath).getAbsoluteFile();
try {
interpret(f, readFile(f), stack);
}
filepath = file.getParentFile().getAbsolutePath() + "/" + filepath;
}
File f = new File(filepath).getAbsoluteFile();
try {
interpret(f, readFile(f), stack);
}
catch (IOException e) {
throw new ISBPLError("IO", "Couldn't find file " + filepath + " required by include keyword.");
catch (IOException e) {
throw new ISBPLError("IO", "Couldn't find file " + filepath + " required by include keyword.");
}
included.add(filepath);
}
};
break;
@ -758,6 +765,22 @@ public class ISBPL {
functionStack.peek().put(name, func);
}
private String getFilePathForInclude(Stack<ISBPLObject> stack, File file) {
ISBPLObject s = stack.pop();
String filepath = toJavaString(s);
processPath:
{
if (filepath.startsWith("/"))
break processPath;
if (filepath.startsWith("#")) {
filepath = System.getenv().getOrDefault("ISBPL_PATH", "/usr/lib/isbpl") + "/" + filepath.substring(1);
break processPath;
}
filepath = file.getParentFile().getAbsolutePath() + "/" + filepath;
}
return filepath;
}
private int createFunction(int i, String[] words, Stack<ISBPLObject> stack) {
i++;
String name = words[i];
@ -1357,12 +1380,14 @@ class ISBPLDebugger extends Thread {
}
class ISBPLStreamer {
public static final int CREATE_FILE = 1;
public static final int CREATE_SOCKET = 2;
public static final int READ = 3;
public static final int WRITE = 4;
public static final int AREAD = 5;
public static final int AWRITE = 6;
public static final int CREATE_FILE_IN = 0;
public static final int CREATE_FILE_OUT = 1;
public static final int CREATE_SOCKET = 2;
public static final int CLOSE = 3;
public static final int READ = 4;
public static final int WRITE = 5;
public static final int AREAD = 6;
public static final int AWRITE = 7;
static class ISBPLStream {
final InputStream in;
@ -1374,6 +1399,11 @@ class ISBPLStreamer {
this.in = in;
this.out = out;
}
public void close() throws IOException {
this.in.close();
this.out.close();
}
}
final ISBPL isbpl;
@ -1387,12 +1417,31 @@ class ISBPLStreamer {
public void action(Stack<ISBPLObject> stack, int action) throws IOException {
ISBPLStream stream;
ISBPLObject s, i;
File f;
switch (action) {
case CREATE_FILE:
case CREATE_FILE_IN:
s = stack.pop();
s.checkType(isbpl.getType("string"));
File f = new File(isbpl.toJavaString(s));
stream = new ISBPLStream(new FileInputStream(f), new FileOutputStream(f));
f = new File(isbpl.toJavaString(s));
stream = new ISBPLStream(new FileInputStream(f), new OutputStream() {
@Override
public void write(int b) throws IOException {
throw new ISBPLError("IllegalArgument", "Can't write to a FILE_IN stream!");
}
});
streams.add(stream);
stack.push(new ISBPLObject(isbpl.getType("int"), stream.id));
break;
case CREATE_FILE_OUT:
s = stack.pop();
s.checkType(isbpl.getType("string"));
f = new File(isbpl.toJavaString(s));
stream = new ISBPLStream(new InputStream() {
@Override
public int read() throws IOException {
throw new ISBPLError("IllegalArgument", "Can't read a FILE_OUT stream!");
}
}, new FileOutputStream(f));
streams.add(stream);
stack.push(new ISBPLObject(isbpl.getType("int"), stream.id));
break;
@ -1423,7 +1472,17 @@ class ISBPLStreamer {
try {
streams.get(((int) i.object)).out.write(((int) bte.toLong()));
} catch (IndexOutOfBoundsException e) {
throw new ISBPLError("IllegalArgument", "streamid STREAM_READ stream called with non-existing stream argument");
throw new ISBPLError("IllegalArgument", "byte streamid STREAM_WRITE stream called with non-existing stream argument");
}
break;
case CLOSE:
i = stack.pop();
i.checkType(isbpl.getType("int"));
try {
ISBPLStream strm = streams.get(((int) i.object));
strm.close();
} catch (IndexOutOfBoundsException e) {
throw new ISBPLError("IllegalArgument", "streamid STREAM_CLOSE stream called with non-existing stream argument");
}
break;
default:

4
helloworld.isbpl Normal file
View file

@ -0,0 +1,4 @@
func main {
"Hello World!\n" puts
0
}

22
helloworldgen.isbpl Normal file
View file

@ -0,0 +1,22 @@
"#stream.isbpl" include
"#iota.isbpl" include
func main {
pop
def id "helloworld.isbpl" STREAM_CREATE_FILE_OUT stream =id
def s "func main {\n \"Hello World!\\n\" puts\n 0\n}" _array =s
def i 0 =i
while { i s alen lt } {
( s i aget ) id STREAM_WRITE stream
i inc
}
id STREAM_CLOSE stream
"testing\n" puts
"helloworld.isbpl" include
main
0
}

4
iota.isbpl Normal file
View file

@ -0,0 +1,4 @@
def iota_storage 0 =iota_storage
func iota { iota_storage dup ++ =iota_storage }
func riota { 0 1 =iota_storage }

View file

@ -1,11 +1,14 @@
"#iota.isbpl" include
native stream
def STREAM_CREATE_FILE 1 =STREAM_CREATE_FILE
def STREAM_CREATE_SOCKET 2 =STREAM_CREATE_SOCKET
def STREAM_READ 3 =STREAM_READ
def STREAM_WRITE 4 =STREAM_WRITE
def STREAM_CREATE_FILE_IN riota =STREAM_CREATE_FILE_IN
def STREAM_CREATE_FILE_OUT iota =STREAM_CREATE_FILE_OUT
def STREAM_CREATE_SOCKET iota =STREAM_CREATE_SOCKET
def STREAM_CLOSE iota =STREAM_CLOSE
def STREAM_READ iota =STREAM_READ
def STREAM_WRITE iota =STREAM_WRITE
"not implemented:" #
"def STREAM_AREAD 5 =STREAM_AREAD" #
"def STREAM_AWRITE 6 =STREAM_AWRITE" #
"def STREAM_AREAD iota =STREAM_AREAD" #
"def STREAM_AWRITE iota =STREAM_AWRITE" #

17
time.isbpl Normal file
View file

@ -0,0 +1,17 @@
native time
func getms {
0 time
}
func sleep {
time pop
}
func delay {
time pop
}
func delays {
1000 * time pop
}