Closed OldLiu001 closed 3 weeks ago
Hi @OldLiu001
Congrats to you for making your own VBScript implementation.
I made a pull request (#640) which enable the runtest.py
script to run mal implementation tests on Windows. You may refer to that PR and see if the script helps.
Hi @OldLiu001
Congrats to you for making your own VBScript implementation.
I made a pull request (#640) which enable the
runtest.py
script to run mal implementation tests on Windows. You may refer to that PR and see if the script helps.
Thank you for your contribution.
I test my impl with this script (Batch File):
@echo off
pushd "%~dp0"
rem goto p
for %%a in (
step0_repl
step1_read_print
step2_eval
step3_env
step4_if_fn_do
step5_tco
step6_file
step7_quote
step8_macros
step9_try
stepA_mal
) do (
echo @pushd "%%~dp0" ^& @cscript -nologo %%a.vbs > .\impls\vbs\run_%%a.cmd
python runtest.py --rundir "impls\vbs" --test-timeout 1800 --deferrable --optional --no-pty "..\tests\%%a.mal" "run_%%a.cmd"
del .\impls\vbs\run_%%a.cmd
rem pause
)
exit
It passed all the tests.
@kanaka Thank you for your advice.
I just tried the following:
runtest.py
to the unupdated version.runtest.py
with and without --no-pty
argument.Then I got:
$ env STEP=step0_repl MAL_IMPL=vbs ../../runtest.py --deferrable --optional ../tests/step0_repl.mal -- ../vbs/run
Did not receive one of following prompt(s): ['[^\\s()<>]+> ']
Got : '\x1b[6n'
Exception: SystemExit(1,)
Output before exception:
^[[30;1R
$ env STEP=step0_repl MAL_IMPL=vbs ../../runtest.py --deferrable --optional --no-pty ../tests/step0_repl.mal -- ../vb
s/run
Testing basic string
TEST: 'abcABC123' -> ['',abcABC123] -> FAIL (line 3):
Expected : '.*\nabcABC123'
Got : 'abcABC123'
Testing string containing spaces
TEST: 'hello mal world' -> ['',hello mal world] -> FAIL (line 7):
Expected : '.*\nhello\\ mal\\ world'
Got : 'hello mal world'
Testing string containing symbols
TEST: '[]{}"\'* ;:()' -> ['',[]{}"'* ;:()] -> FAIL (line 11):
Expected : '.*\n\\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)'
Got : '[]{}"\'* ;:()'
Test long string
TEST: 'hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"\'* ;:() []{}"\'* ;:() []{}"\'*)' -> ['',hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)] -> FAIL (line 16):
Expected : '.*\nhello\\ world\\ abcdefghijklmnopqrstuvwxyz\\ ABCDEFGHIJKLMNOPQRSTUVWXYZ\\ 0123456789\\ \\(\\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\)'
Got : 'hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"\'* ;:() []{}"\'* ;:() []{}"\'*)'
Non alphanumeric characters
TEST: '!' -> ['',!] -> FAIL (line 20):
Expected : '.*\n\\!'
Got : '!'
TEST: '&' -> ['',&] -> FAIL (line 22):
Expected : '.*\n\\&'
Got : '&'
TEST: '+' -> ['',+] -> FAIL (line 24):
Expected : '.*\n\\+'
Got : '+'
TEST: ',' -> ['',,] -> FAIL (line 26):
Expected : '.*\n\\,'
Got : ','
TEST: '-' -> ['',-] -> FAIL (line 28):
Expected : '.*\n\\-'
Got : '-'
TEST: '/' -> ['',/] -> FAIL (line 30):
Expected : '.*\n\\/'
Got : '/'
TEST: '<' -> ['',<] -> FAIL (line 32):
Expected : '.*\n\\<'
Got : '<'
TEST: '=' -> ['',=] -> FAIL (line 34):
Expected : '.*\n\\='
Got : '='
TEST: '>' -> ['',>] -> FAIL (line 36):
Expected : '.*\n\\>'
Got : '>'
TEST: '?' -> ['',?] -> FAIL (line 38):
Expected : '.*\n\\?'
Got : '?'
TEST: '@' -> ['',@] -> FAIL (line 40):
Expected : '.*\n\\@'
Got : '@'
TEST: '^' -> ['',^] -> FAIL (line 43):
Expected : '.*\n\\^'
Got : '^'
TEST: '_' -> ['',_] -> FAIL (line 45):
Expected : '.*\n\\_'
Got : '_'
TEST: '`' -> ['',`] -> FAIL (line 47):
Expected : '.*\n\\`'
Got : '`'
TEST: '~' -> ['',~] -> FAIL (line 49):
Expected : '.*\n\\~'
Got : '~'
------- Optional Functionality --------------
------- (Not needed for self-hosting) -------
Non alphanumeric characters
TEST: '#' -> ['',#] -> SOFT FAIL (line 58):
Expected : '.*\n\\#'
Got : '#'
TEST: '$' -> ['',$] -> SOFT FAIL (line 60):
Expected : '.*\n\\$'
Got : '$'
TEST: '%' -> ['',%] -> SOFT FAIL (line 62):
Expected : '.*\n\\%'
Got : '%'
TEST: '.' -> ['',.] -> SOFT FAIL (line 64):
Expected : '.*\n\\.'
Got : '.'
TEST: '|' -> ['',|] -> SOFT FAIL (line 66):
Expected : '.*\n\\|'
Got : '|'
FAILURES:
FAILED TEST (line 3): abcABC123 -> ['',abcABC123]:
Expected : '.*\nabcABC123'
Got : 'abcABC123'
FAILED TEST (line 7): hello mal world -> ['',hello mal world]:
Expected : '.*\nhello\\ mal\\ world'
Got : 'hello mal world'
FAILED TEST (line 11): []{}"'* ;:() -> ['',[]{}"'* ;:()]:
Expected : '.*\n\\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)'
Got : '[]{}"\'* ;:()'
FAILED TEST (line 16): hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*) -> ['',hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)]:
Expected : '.*\nhello\\ world\\ abcdefghijklmnopqrstuvwxyz\\ ABCDEFGHIJKLMNOPQRSTUVWXYZ\\ 0123456789\\ \\(\\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\ \\;\\:\\(\\)\\ \\[\\]\\{\\}\\"\\\'\\*\\)'
Got : 'hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"\'* ;:() []{}"\'* ;:() []{}"\'*)'
FAILED TEST (line 20): ! -> ['',!]:
Expected : '.*\n\\!'
Got : '!'
FAILED TEST (line 22): & -> ['',&]:
Expected : '.*\n\\&'
Got : '&'
FAILED TEST (line 24): + -> ['',+]:
Expected : '.*\n\\+'
Got : '+'
FAILED TEST (line 26): , -> ['',,]:
Expected : '.*\n\\,'
Got : ','
FAILED TEST (line 28): - -> ['',-]:
Expected : '.*\n\\-'
Got : '-'
FAILED TEST (line 30): / -> ['',/]:
Expected : '.*\n\\/'
Got : '/'
FAILED TEST (line 32): < -> ['',<]:
Expected : '.*\n\\<'
Got : '<'
FAILED TEST (line 34): = -> ['',=]:
Expected : '.*\n\\='
Got : '='
FAILED TEST (line 36): > -> ['',>]:
Expected : '.*\n\\>'
Got : '>'
FAILED TEST (line 38): ? -> ['',?]:
Expected : '.*\n\\?'
Got : '?'
FAILED TEST (line 40): @ -> ['',@]:
Expected : '.*\n\\@'
Got : '@'
FAILED TEST (line 43): ^ -> ['',^]:
Expected : '.*\n\\^'
Got : '^'
FAILED TEST (line 45): _ -> ['',_]:
Expected : '.*\n\\_'
Got : '_'
FAILED TEST (line 47): ` -> ['',`]:
Expected : '.*\n\\`'
Got : '`'
FAILED TEST (line 49): ~ -> ['',~]:
Expected : '.*\n\\~'
Got : '~'
SOFT FAILED TEST (line 58): # -> ['',#]:
Expected : '.*\n\\#'
Got : '#'
SOFT FAILED TEST (line 60): $ -> ['',$]:
Expected : '.*\n\\$'
Got : '$'
SOFT FAILED TEST (line 62): % -> ['',%]:
Expected : '.*\n\\%'
Got : '%'
SOFT FAILED TEST (line 64): . -> ['',.]:
Expected : '.*\n\\.'
Got : '.'
SOFT FAILED TEST (line 66): | -> ['',|]:
Expected : '.*\n\\|'
Got : '|'
TEST RESULTS (for ../tests/step0_repl.mal):
5: soft failing tests
19: failing tests
0: passing tests
24: total tests
The results show that when WSL communicates with Windows native console programs, some unexpected behavior may occur, leading to test failure.
In order to be compatible with Windows, it seems that runtest.py
must make some big changes.
I also agree with you that patching runtest.py
and repeating scripts run
with run.cmd
is very inelegant. I'm wondering if there is a more elegant way to do this, and if you have any suggestions or ideas, please feel free to let me know.
Besides, I have taken note of incremental process / layout changing problem. But I think we should finish our discussion of the current issue and then consider some relative details.
Can you run those tests again with --debug-file debug.log
added to the runtest command? I would be interested to see what the content of that would be for each case (for the second one, you don't need to post the full file, just the top 30 lines or so). Might indicate what is going wrong and hopefully there is a simple way to work around it.
@kanaka I did the following tests:
runtest.py
.The results of the bash impl + WSL
test are as follows.
$ env STEP=step0_repl MAL_IMPL=bash ../../runtest.py --deferrable --optional --debug-file wsl_bash_withpty.log ../tests/step0_repl.mal -- ../bash/run
...
TEST RESULTS (for ../tests/step0_repl.mal):
0: soft failing tests
0: failing tests
24: passing tests
24: total tests
$ env STEP=step0_repl MAL_IMPL=bash ../../runtest.py --deferrable --optional --no-pty --debug-file wsl_bash_nopty.log
../tests/step0_repl.mal -- ../bash/run
Did not receive one of following prompt(s): ['[^\\s()<>]+> ']
Got : ''
Exception: SystemExit(1,)
Output before exception:
Log files are as follows:
$ head wsl_vbs_nopty.log
user> abcABC123
user> hello mal world
user> []{}"'* ;:()
user> hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)
user> !
user> &
user> +
user> ,
user> -
user> /
$ od -t x1 wsl_vbs_withpty.log
0000000 1b 5b 36 6e
0000004
$ od -t x1 wsl_bash_nopty.log
0000000
$ head wsl_bash_withpty.log
user> abcABC123
abcABC123
user> hello mal world
hello mal world
user> []{}"'* ;:()
[]{}"'* ;:()
user> hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)
hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*)
user> !
!
So far I have reached the following conclusions:
WSL + bash impl + pty
works normally, and WSL + vbs impl + nopty
may work normally after runtest.py
is modified.WSL + vbs impl + pty
has 4 bytes, and log of WSL + bash impl + nopty
is an empty file.WSL + bash impl + pty
will repeat the standard input in the standard output, but WSL + vbs impl + nopty
will not.1b 5b 36 6e
is an ANSI escape sequence: ESC [ 6 n
. From https://man7.org/linux/man-pages/man4/console_codes.4.html :
ECMA-48 Status Report Commands ESC [ 5 n Device status report (DSR): Answer is ESC [ 0 n (Terminal OK). ESC [ 6 n Cursor position report (CPR): Answer is ESC [ y ; x R, where x,y is the cursor location.
Not sure exactly how to continue, but maybe this will help.
(welcome back @kanaka , glad you're okay. got me a bit worried, I must say.)
Let me briefly summarize the above discussion:
runtest.py
modified by @cy20lin has been fully tested on the Windows platform, but the description of various details of the changes in runtest.py
is lacking.WSL
to achieve Windows platform compatibility without changing the main logic of the project's original runtest.py
, but it seems that things are not as simple as we thought. Maybe we need to re-encounter and solve all the problems that @cy20lin encountered and solved before.My personal advice:
@kanaka Regarding the structural changes you mentioned in merging 'EvaluateAST' and 'MacroExpand' into 'Evaluate', I went to #587 , and since it's been a long time since I finished my vbs implementation, I went back to my code structure.
I found it interesting that when I was writing code, I already realized that normal functions and macros were identical in evaluation (that is, they were identical except for whether the parameters were evaluated), and I used the same class to represent both structures. I implemented the evaluation procedure as two methods of the 'MalProcedure' class, 'Apply' and 'ApplyWithoutEval'. I even added a new method, 'MacroApply'. It differs from 'ApplyWithoutEval' only in that it checks whether 'Procedure' is a macro at its head, and the logic I implemented to distinguish between functions and macros was to use a different class attribute as a tag.
I even unified the interfaces for 'vbs functions' and 'mal functions' and 'mal macro' calls (although the object-oriented implementation of vbs has no concept of interfaces, but it is a dynamically typed language, and two classes can be considered to implement the same interface as long as they have the same properties and methods). This has the advantage of using the same upper level code for processing.
Regarding evalast merging into eval, I think this is really a good change because evalast is only called once in eval, and there is no need to implement it as a separate function. And it does integrate the logic of the code. But if you look at my implementation, you'll see that my TCO implementation is very elegant (forgive me for bragging here, lol). The core idea of my tco implementation is that if the last step a function takes is to call another function and then return to the previous layer, then we can swap the order of the two steps, that is, return to the previous layer before making the function call. I use lazy evaluation to delay EVAL in tail recursion scenarios, so separating evalast and eval does not increase the call stack or cause my code to become verbose and uncontrollable.
In summary, I found that some of the ideas for merging code structures were already present in my implementation, and some didn't seem too bad for my implementation, so I thought it would be best to keep the current version.
Also something I discovered while writing my implementation is that if you switch the order in which some functions are implemented in the flow, many functions can be implemented with other functions, that is, the code can contain more parts that implement mal using mal itself. Using the mal language itself to implement mal's other functions may cause the code to run less efficiently, but I think that's cool, right?
@dubek Thanks! I'm glad to be able to spend time on this again.
@OldLiu001 runtest.py
is already too complicated and a maintenance burden so I'm not willing to make it more complicated like proposed in #640. It would be great to support Windows implementations but I'm not willing to complicate runtest.py
that much to support a small handful of implementations. The software landscape has changed and it's pretty rare for languages to only support Windows any more (vbscript being an obvious exception).
Anyways, thank for the detailed output and good thought to compare with bash. That has given me an idea for a minor change to runtest to support Windows+WSL in--no-pty
mode. The reason it's failing is because the vbscript implementation is not echo'ing the input/test form back to the terminal. Please try this tweak to runtest.py
and see if it changes things: https://github.com/kanaka/mal/compare/master...runtest-no-pty-no-echo?diff=unified&w=.
If it's still broken, I would be interested in the the same debug output from vbscript and bash as before. I'm pretty confident that we can get this to work without the full refactoring of runtest.py
.
Also something I discovered while writing my implementation is that if you switch the order in which some functions are implemented in the flow, many functions can be implemented with other functions, that is, the code can contain more parts that implement mal using mal itself. Using the mal language itself to implement mal's other functions may cause the code to run less efficiently, but I think that's cool, right?
Yeah, that's true that there are a number of functions that could be implemented in mal itself (and some special forms that could be implemented in mal itself using macros). But the primary goal of mal is pedagogical (learning tool). That goal has two parts: 1. learning about Lisp by implementing a Lisp interpreter, 2. learning about the host language by implementing a significant application in that language. The choices about the order of the steps and which functions are implemented in mal vs in the host language is a balance between those two learning goals.
In each step I try and introduce a core Lisp concept and also leverage some new aspects of the host language. If the goal was only learning Lisp then the order of steps 5-A would be very different: macros and try/cache would be very early so that those could be used to implement many of the core functions and some of the special forms directly in mal itself. But the current order and when/how functions are implemented is trying to balance those two learning goals. For example, not
is implemented as a function in mal itself in step 4. This is a weird choice if the goal of mal were primarily to implement a Lisp interpreter. However, it's serves a really useful learning goal to show early on that you can use mal to implement parts of mal and it enables better testing of the fn*
form at that point in the flow.
@kanaka I did the following tests:
runtest.py
you lately provided.make "test^vbs^step0"
, it passed all the test smoothly.make "test^vbs^step1"
, I test it many times and make sure it will stuck in first Regular Expression check.
$ env STEP=step1_read_print MAL_IMPL=vbs ../../runtest.py --deferrable --optional --no-pty --debug-file vbs_step1.log ../tests/step1_read_print.mal -- ../vbs/run
...
TEST: '"}"' -> ['',"}"] -> SUCCESS TEST: '"~"' -> ['',"~"] -> SUCCESS TEST: '"!"' -> ['',"!"] -> SUCCESS Testing reader errors TEST: '(1 2' -> ['.(EOF|end of input|unbalanced).',] -> TIMEOUT (line 142)
Exception: TestTimeout('TIMEOUT (line 142)',) Output before exception: user> Exception: unbalanced parentheses.
make: *** [Makefile:238: test^vbs^step1] Error 1
$ tail vbsstep1.log user> "[" user> "]" user> "^" user> "" user> "`" user> "{" user> "}" user> "~" user> "!" user> user> Exception: unbalanced parentheses.
[vbs_step1.log](https://github.com/user-attachments/files/16564280/vbs_step1.log)
If it's still broken, I would be interested in the the same debug output from vbscript and bash as before. I'm pretty confident that we can get this to work without the full refactoring of .
runtest.py
$ env STEP=step1_read_print MAL_IMPL=bash ../../runtest.py --deferrable --optional --debug-file bash_step1.log ../te
sts/step1_read_print.mal -- ../bash/run
...
TEST RESULTS (for ../tests/step1_read_print.mal):
0: soft failing tests
0: failing tests
118: passing tests
118: total tests
Part of bash_step1.log
:
user> 1
1
user> 7
7
user> 7
7
...(skip)
user> "~"
"~"
user> "!"
"!"
user> (1 2
Error: expected ')', got EOF
user> [1 2
Error: expected ']', got EOF
user> "abc
Error: expected '"', got EOF
...(skip)
user> 1;\\\
1
user> 1;`
1
user> 1; &()*+,-./:;<=>?@[]^_{|}~
1
user>
(EOF)
@OldLiu001 looks like runtest is now working for vbs using --no-pty
. That new problem appears to be because vbs errors (to stderr) are out of order with normal prints (to stdout). In other words, the output from that vbs as read by runtest was:
user> user> Exception: unbalanced parentheses.
but runtest is expecting them to be in correct order (the order the implementation wrote them):
user> Exception: unbalanced parentheses. user>
This likely means that stderr is buffered and stdout is not. That's pretty typical even in Linux/macos. That's one of the things that the pty mode addresses (in addition to allowing line editing i.e. libedit/GNU readline, to be tested properly). There are a few ways to address that:
stdbuf -o0 -e0 cscript ...
. Not 100% certain this will work in calls to windows programs but this would work in linux/macos to unbuffer both stdout and stderr.@kanaka Thank you for your precise point of view.
I wrote test_stderr_buffered.mal
for testing:
$ cat test_stderr_buffered.mal
"a"
(1 2
"c"
$ cscript.exe -nologo step1_read_print.vbs < test_stderr_buffered.mal
user> "a"
user> user> Exception: unbalanced parentheses.
"c"
user>
The results show that there is indeed a problem with standard error streams being buffered, and your sense is keen!
I looked through the vbs manual and found no information about refreshing the output cache.
Then I test it on cmd.exe
without WSL
participate in:
D:\@PubCodes\mal\impls\vbs>cscript -nologo step1_read_print.vbs < test_stderr_buffered.mal
user> "a"
user> Exception: unbalanced parentheses.
user> "c"
user>
D:\@PubCodes\mal\impls\vbs>
I was surprised to find that the results were returned in the correct order.
Next I tried to fix it with:
$ stdbuf -o0 -e0 cscript.exe -nologo step1_read_print.vbs < test_stderr_buffered.mal
user> "a"
user> user> Exception: unbalanced parentheses.
"c"
user>
But it didn't work.
Combined with the above information, please feel free to advise.
I will also continue to search for information from the Internet, and if the cache problem is still not solved, then I will consider using StdOut
instead of all StdErr
.
I avoided the buffered stderr problem by introducing cmd.exe
as a mediator and merging the error output stream into the standard output stream within it.
impls/vbs/run
#!/bin/bash
cmd.exe /c "cscript -nologo $(dirname $0)/${STEP:-stepA_mal}.vbs "${@}" 2>&1"
Later, I found that introducing cmd
as an intermediary would cause the parameter tests for step6
to fail, so I removed it again and changed the entire StdErr
in my implementation to StdOut
.
Now we have a new problem where runtest.py
gets stuck when it encounter a test sample of (result ignored)
.
make "test^vbs^step1" (partial)
TEST: '({})' -> ['',({})] -> SUCCESS
Testing read of comments
TEST: ' ;; whole line comment (not an exception)' -> ['',] -> TIMEOUT (line 226)
Exception: TestTimeout('TIMEOUT (line 226)',)
Output before exception:
user>
make: *** [Makefile:238: test^vbs^step1] Error 1
make "test^vbs^stepA" (partial)
Testing readline
TEST: '(readline "mal-user> ")' -> ['',] -> TIMEOUT (line 9)
Exception: TestTimeout('TIMEOUT (line 9)',)
Output before exception:
mal-user>
make: *** [Makefile:238: test^vbs^stepA] Error 1
$ tail vbs_step1.log
user> {}
user> {"abc" 1}
user> {"a" {"b" 2}}
user> {"a" {"b" {"c" 3}}}
user> {"a" {"b" {"cde" 3}}}
user> {"a1" 1 "a2" 2 "a3" 3}
user> {:a {:b {:cde 3}}}
user> {"1" 1}
user> ({})
user> user>
$ tail vbs_stepA.log
Mal [VBScript]
user> mal-user>
Again, the Bash impl output for debug:
bash_step1.log (partial)
user> ({})
({})
user> ;; whole line comment (not an exception)
../bash/printer.sh: line 60: declare: yes: not found
user> 1 ; comment after expression
1
user> 1; comment after expression
1
bash_stepA.log (partial)
Mal [bash]
user> (readline "mal-user> ")
mal-user> "hello"
"\"hello\""
user> (= "something bogus" *host-language*)
false
@kanaka The WSL
environment on Github Action
has been set up and the results are consistent with what I tested locally. I can already see the dawn of victory!
Finally get rid of the extra run.cmd
lol.
I tried:
res = r.read_to_prompt(['\r\n[^\\s()<>]+> ', '\n[^\\s()<>]+> '],
timeout=args.test_timeout)
->
res = r.read_to_prompt(['\r\n[^\\s()<>]+> ', '\n[^\\s()<>]+> ', '[^\\s()<>]+> '],
timeout=args.test_timeout)
Although it will not continue to stuck in the result ignored
tests, it will cause misalignment of the output, which will cause some correct results to be mistaken for errors.
More logs:
$ cscript.exe -nologo step1_read_print.vbs < ../tests/step1_read_print.mal
... (ignored)
user> user> {} <-- Synchronize with the start position of the log above
user> user> {"abc" 1}
user> user> {"a" {"b" 2}}
user> user> {"a" {"b" {"c" 3}}}
user> user> {"a" {"b" {"cde" 3}}}
user> user> user> user> {"a1" 1 "a2" 2 "a3" 3}
user> user> {:a {:b {:cde 3}}}
user> user> {"1" 1}
user> user> ({})
user> user> user> user> user> 1 <-- runtest.py will stuck in this line
user> user> 1
user> user> user> user> (deref a)
user> user> user> user> a:
user> user> user> user> user> user> user> user> user> (with-meta [1 2 3] {"a" 1})
user> user> user> user> user> user> "\n"
... (ignored)
$ cscript.exe -nologo stepA_mal.vbs < ../tests/stepA_mal.mal
Mal [VBScript]
user> user> user> user> user> user> user> user> user> mal-user> "\"hello\"" <-- runtest.py will stuck in this line
user> user> user> user> user> user> user> false
user> user> user> user> user> user> user> user> user> user> user> user> (atom {"+" #<function>})
... (ignored)
Not sure how to fix it, and would like your comments and suggestions.
I think both failures are related to when newline are being printed out and the fact that when in test mode the user's input is not being echo'd (which would include a final newline).
For example, I think the first failure is caused by this check in your REPL routine:
If strRes <> "" Then
WScript.Echo strRes
End If
I think that is preventing a newline in cases where the eval result is empty.
For the second failure related to the readline core function, I suspect there is again a newline issue but I'm not exactly sure from the result what's going on. Can you try adding a newline prior to every prompt? Something like this:
WScript.StdOut.Write "\nuser> "
You won't necessarily want that for interactive repl usage, but it might be enlightening to figure out what's going on with the tests.
@kanaka Accurate insight!
Now that I've figured out the origin of all the problems, I've decided not to change runtest.py
at all, but instead to encapsulate an IOWrap
class in vbs, which has the option of choosing a different Repeat Form
internally and whether to merge the error output stream
into the standard output stream
.
The rest of the code calls this IOWrap
class, so we avoid code redundancy.
Externally, I passed several environment variables inside the run
script to both WSL and vbs to regulate the behavior of the vbs implementation during testing.
Based on the above steps, the problem has been solved almost perfectly, both in terms of not changing runtest.py
at all and in terms of the elegance of the code logic.
Thank you for your patient advice.
I would also like to thank @cy20lin and @dubek for their attention and selfless help.
@kanaka I have tried the self-hosted test you mentioned and it passed all the tests (albeit slowly). I'm not familiar with rebase's flow, so I probably won't be able to combine some commits, but I've prefixed each of my commits with the following command:
git-filter-repo --commit-callback 'commit.message = (b"vbs: " + commit.message) if commit.author_email==b"632171029@qq.com" else commit.message;return commit' --force
In addition, the number of implementations in the readme file has been modified.
@kanaka I forcibly overwrote my master branch using the kanaka/mal/master
branch, then cherry picked all vbs related commits from the previous records and applied them to the master branch.
That should be all right this time.
@OldLiu001 Merged! Thanks for your work on this and pushing through even though it was tedious. Hopefully any future implementations that support Windows will have a smoother path because they can refer to what you did to get things working. Any plans for future implementations? Want to try getting the powershell implementation running/testing in Windows (i.e. adding a new powershell line to IMPLS.yaml
for windows)?
@kanaka Thank you for your patience.
My next plan is to try to complete an implementation using batch scripts
at my leisure.
Regarding the powershell
implementation you mentioned, I often use the output of the powershell implementation as a reference when writing the vbs implementation, so it should not be a problem to run on windows.
However, in order for runtest.py
to work, we may also need to wrap some interfaces like the io.vbs
of vbs implementation to complete the switch between different output repetition patterns.
Hello everyone, maintainers & contributors!
After more than half a year, I finally implement it.
During this period, I benefited a lot and felt the charm of Lisp language. Thank you for the project and its contributors.
Unfortunately, it seems that the makefile file and python script cannot work on Windows, and Vbscript cannot run in linux.
But I have manually tested all the examples in the tests folder and make sure I passed them (run mal impl in VBScript are also passed).
Nevertheless, I still want to contribute my learning process and achievements to this project to attract future generations.
The readme file has already updated for others to run my script.