Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vbs: merge {macro,quasiquote}expand into EVAL, add DEBUG-EVAL #703

Merged
merged 10 commits into from
Oct 29, 2024

Conversation

asarhaddon
Copy link
Contributor

Eval_ast was already reserved to lists.

env.vbs: rewrite env.get with a string argument and without exception because this is convenient for DEBUG-EVAL.

types.vbs: after a macro expansion, evaluate with TCO.

Take the opportunity to remove an unused variable from first steps.
This change is not useful per se, but prepares DEBUG-EVAL.
@asarhaddon
Copy link
Contributor Author

Hello.
I would like a little help with the VBS implementation. I cannot test locally, and the CI takes several minutes for a sometimes cryptic error message.

For example, the current head outputs Object required, see https://github.com/kanaka/mal/actions/runs/11477089378/job/31938448096?pr=703.
@kanaka or @OldLiu001, can you give me a more interesting error message and/or explanations about this issue?

By the way, the following env.vbs arguably improves readability, and probably improve performances (the documentation explicitly recommends against recursion, and there are a lot of environment traversals, especially with DEBUG-EVAL), but I would appreciate if someone with VBA available works on the debugging phase.

Option Explicit
                         
Function NewEnv(objOuter)
        NewEnv = New Environment
        NewEnv.Outer = objOuter
End Function
                 
Class Environment                 
        Private objBinds, objOuter
                                      
        Private Sub Class_Initialize()                             
                Set objBinds = CreateObject("Scripting.Dictionary")
                ' objOuter Is Nothing
        End Sub
                                         
        Public Property Set Outer(objEnv)
                Set objOuter = objEnv
        End Property

        Public Sub Add(varKey, varValue)            
                Set objBinds.Item(varKey) = varValue
        End Sub
                                     
        Public Function [Get](varKey)
                Dim objEnv = Me
                Do Until objEnv.objBinds.Exists(varKey)
                        objEnv = objEnv.objOuter            
                        If TypeName(objEnv) = "Nothing" Then
                                ' [Get] Is Nothing
                                Exit Function
                        End If
                Loop                               
                Set [Get] = objEnv.objBinds(varKey)
        End Function
End Class

@OldLiu001
Copy link
Contributor

OldLiu001 commented Oct 23, 2024

@asarhaddon In the VBS language, Set is required for Object assignment, and other types (Booleans, Strings, Numbers, etc.) must be directly assigned (if other types use Set assignment, an error will be reported).

Set obj = New RegExp
Set obj = Nothing
bool = True
bool = False
num = 3.14
str = "String"

To be honest, I also think this rule is a little strange, and Microsoft's later language, VB.Net, has removed this restriction.
'Let' and 'Set' assignment statements are no longer supported

Regarding your proposal to replace recursion with iteration, I think it is a good modification, especially in a language like VBS that does not have TCO, and can also improve efficiency.

@asarhaddon
Copy link
Contributor Author

Thanks. That may be obvious for daily users, but not from the online docs to a beginner.

The tests now pass, and take 75 minutes (60 before DEBUG-EVAL). We will see if the env.get optimization helps.

@OldLiu001
Copy link
Contributor

You're welcome.
It seems that you are having some minor trouble with grammar, I have made some comments.

@OldLiu001
Copy link
Contributor

OldLiu001 commented Oct 24, 2024

@asarhaddon Try this:
env.vbs

Option Explicit

Function NewEnv(objOuter)
	Set NewEnv = New Environment
	Set NewEnv.Outer = objOuter
End Function

Class Environment
	Public objOuter
	Public objBinds
	Private Sub Class_Initialize()
		Set objBinds = CreateObject("Scripting.Dictionary")
		Set objOuter = Nothing
	End Sub
	
	Public Property Set Outer(objEnv)
		Set objOuter = objEnv
	End Property

	Public Sub Add(varKey, varValue)
		Set objBinds.Item(varKey) = varValue
	End Sub

	Public Function [Get](varKey)
		Dim objEnv, varRet
		Set objEnv = Me
		Do
			If objEnv.objBinds.Exists(varKey) Then
				Set varRet = objEnv.objBinds(varKey)
				Exit Do
			End If
			Set objEnv = objEnv.objOuter
			If TypeName(objEnv) = "Nothing" Then
				Set varRet = Nothing
				Exit Do
			End If
		Loop

		Set [Get] = varRet
	End Function
End Class

@asarhaddon
Copy link
Contributor Author

I am only seeing your comments. Thanks a lot. I will use your env.vbs.

Make the two remaining attributes public instead of defining getters
and setters.

Thanks to OldLiu001!
@asarhaddon
Copy link
Contributor Author

Done!
Removing the recursion only gets 5 minutes. Good, but that does not even compensate the introduction of DEBUG-EVAL.

@kanaka kanaka merged commit 8610ffb into kanaka:master Oct 29, 2024
4 checks passed
@kanaka
Copy link
Owner

kanaka commented Oct 29, 2024

Wow, that is very slow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants