aya-lang / aya

Pocket sized programs
MIT License
54 stars 3 forks source link

Fix File-resolution on Windows #104

Closed BlazingTwist closed 1 month ago

BlazingTwist commented 1 month ago

While trying to use aya-digit I noticed that "model.json" json.load fails on windows.

I've used FileUtils.resolveFile where it seemed appropriate. (relates to #93 )

I initially thought this fix only applied to windows, but after testing on Ubuntu, it appears Aya also behaves oddly on Linux? (Stop me if the assumptions in my tests are just plain wrong)

The primary cause of Linux weirdness seems to come from my shell having a different working directory than the one I pass to Aya. 'Actual output' indicates the behaviour I am seeing with the current Version of Aya. 'Expected output' is the behaviour using the changes of this PR.


Tests / Affected Instructions

sys.cd, sys.mkdir

test.aya:

"dir1" :{sys.mkdir}
"./dir1" :{sys.cd}
"dir2" :{sys.mkdir}

~/dir3$ java -jar /path/to/aya.jar /path/to/test /path/to/test/test.aya

Expected new directories:

Actual new directories:


sys.set_ad, sys.readdir

test.aya

"../../" :{sys.set_ad}
"../" :{sys.cd}
"." :{sys.readdir}
"" :{sys.cd}           .# reset working directory to aya directory
"." :{sys.readdir}

~/dir3$ java -jar /path/to/aya.jar /path/to/test /path/to/test/test.aya

Expected output:

Actual output:


fstream.O

test.aya

"data.json" 'r :{fstream.O} :id
id 'a :{fstream.O}

~/dir3$ echo "{\"hello\":123,\"world\":456}" > /path/to/test/data.json ~/dir3$ java -jar /path/to/aya.jar /path/to/test /path/to/test/test.aya

Expected output: 11 "{\"hello\":123,\"world\":456}"

Actual output: 0 0 (failed to read file)


image.read and image.write

test.aya

"in.png" :{image.read} :img
"out.png" img.:filename;
img :{image.write}

echo "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12NQWqIJAAHbAPCVVqDlAAAAAElFTkSuQmCC" | base64 -d > /path/to/test/in.png ~/dir3$ java -jar /path/to/aya.jar /path/to/test /path/to/test/test.aya

Expected output:

{,
  1:width;
  1:height;
  "out.png":filename;
  [ 41 -92 34 ]:data;
}

and /path/to/test/out.png is created.

Actual output:

io_err at :{image.read}: unable to use resource in.png. Can't read input file!

> File '/path/to/test/test.aya', line 1, col 22:
1 | "in.png" :{image.read} :img
    ~~~~~~~~~~~~~~~~~~~~~^
2 | "out.png" img.:filename;

Function call traceback:
nick-paul commented 1 month ago

Thanks for always tracking down the platform & filesystem issues, I'm adding some tests on my end to check these cases as well before merging. All of the cases you fixed above look good to me

nick-paul commented 1 month ago

Thanks for the PR, I added a test file test/filesystem.test with the cases you mention above as well as a few additional cases.

The only other issue I found was with :{sys.readdir} which was causing paths to be resolved incorrectly. The bug itself was not introduced in this PR but I included it here since it was relevant to the test cases.

The specific change was that :{sys.readdir} was returning directories with a leading file separator instead of one after the directory name which would cause aya to resolve the path as an absolute path instead of a relative one. For example see below:

Create a directory foo with a single subdirectory bar

aya> "foo" :{sys.mkdir}
aya> "foo" :{sys.cd}
aya> "bar" :{sys.mkdir}

Previously, :{sys.readdir} would return directories with a leading file separator which would be interpreted as an absolute path:

aya> "." :{sys.readdir}
[ "/bar" ]
aya> "." :{sys.readdir} .[0] :{sys.cd}
:{sys.cd} : arg is not a valid path. Did you include a '/' or '' at the end? Received:
"/bar"

Now the separator is after the name so it is properly resolved as a relative path:

aya> "." :{sys.readdir}
[ "bar/" ]
aya> "." :{sys.readdir} .[0] :{sys.cd}
aya> :{sys.wd}
"/path/to/aya/foo/bar/"

If this change works for you, we can go ahead and merge

BlazingTwist commented 1 month ago

Looks good to me, only potential trouble is that comparing against dir1/ fails, since aya returns dir1\.

I suspect the tests aren't meant to be platform independent, but it shouldn't hurt either.