-
1 Attachment(s)
js4vb Javascript Engine w/Debugger and COM
This is a js parser / interpreter in vb6 with x64 number support, COM integration and built in debugging capabilities.
This was built with claude.ai and took about 44 hrs work which is wild for what it is.
Ive already burned through 15 context size limits already.
I am using it in one of my projects and it is stable. I havent had any big problems yet, just some tweaks and small oversights. It should be pretty complete and well tested, but its big, so there will be bugs.
Compiles as a 640k ActiveX dll and has a handful of example projects to show how to use it.
Couple nuances of this engine:
- print is fancy, it can dump arrays and json objects directly
- not case sensitive myVal and myval are the same (dont care actually good)
- function aliases for built in functions is currently unsupported test = alert wont work (works with js declared fx easy fix im sure)
- no regex support (never happening - use a COM object)
- ParseJsonString will look inside string values and auto convert to number including 0x hex, even 64 bit (slightly naughty but perfect for me)
- we use true 64 bit numbers for bigint, not the js spec 53 bit
- COM methods can return native json objects directly to engine: Set myComFunc = json.ParseToCVal(s)
- COM methods can return 64bit numbers directly to engine: Dim v As New CValue: v.LoadNumFromStr(str): Set myComFunc = v
- COM methods can return vb arrays without a problem, auto converted to js array (suck that ms script control)
- can attach js helper functions to COM objects or override COM methods while still able to call real one.
- demo code created on how to sink events, not yet wired into script engine
See the (oldish) readme for the highlights and info below
Dependencies:
- core engine all vb6
- 64 bit numbers requires utypes.dll (open source C std dll)
- COM integration uses dynproxy.dll (open source C std dll - vb CallByName was to limited)
- these dlls are both loaded on demand and included in the git repo
- if you want to use the debugger UI with syntax highlighting you will need scivb2.ocx or sci4vb.ocx -
https://github.com/dzzie/scivb2
https://github.com/dzzie/sci4vb (newer)
Anyway the entire JS core is all regular vb6.
Putting this out under MIT license because we should have all had this forever ago!
I dont really like git, but I made a public repo for this to help everyone track the latest changes. I dont use a dev or release branch so I will try to always keep repo with stable pushs only. That may not be possible if I have to make big changes, but the zip attached below will always be a stable snapshot. It may be a little older as its more work to sync manually.
Public Repo:
https://github.com/dzzie/js4vb
-
Re: VB6 Javascript ES5 AST Parser / Intrepreter
i made a design decision to include full x64 signed number support and break specs with traditional js large number but not quite x64 bs
**Stage 1:**
- Literals (numbers, strings, booleans, null)
- Variables (var)
- Binary operators (+, -, *, /, %, <, >, <=, >=, ==, !=, ===, !==)
- String concatenation
**Stage 2:**
- If/else conditionals
- While/do-while loops
- For loops
- Break/continue
- Logical operators (&&, ||, !)
- Unary operators (!, -, +, ~, typeof, void)
- Update expressions (++, --)
**Stage 3:**
- Functions (declarations & expressions)
- Function calls with parameters
- Return values
- **Closures with captured scope**
- Arrays with indexing
- Objects with properties
- Member access (dot & bracket)
- Recursion
- built in true 64 bit number support with auto promotion and mixing
- Call COM objects from JavaScript
- new ActiveXObject support with UseSafeSubset blocking
- Added JavaScript string API (20+ methods)
- JSON.parse/stringify() - Complete
- Math - all standard methods + constants
- Array - all standard methods
- Array Callback methods: forEach, map, filter, reduce, find, findIndex, some, every
- Error handling (throw/try/catch/finally)
- print can dump objects and arrays like python
- this context supported
- debugger capabilities built in with call stack and variable inspection
- access js objects as COM objects (see below)
- convert copies of js objects to vb variants/scripting.dictionary
Persistent context
AddCode() - build up reusable code
Eval() - evaluate expressions
SetVariable() / GetVariable() - VB6 integration
Global functions:
parseInt (decimal, hex, octal, binary)
parseFloat
isNaN, isFinite, isInteger
encodeURI/decodeURI
encodeURIComponent/decodeURIComponent
escape/unescape
eval
prompt
alert
hex
-
Re: VB6 Javascript ES5 AST Parser / Intrepreter
Very good, very interesting work.
JQuery parsing error
Code:
Unexpected token: x10000 at line 755
I will try to do more tests.
It's a shame that claude.ai doesn't allow new users.
Very good work keep it up
-
1 Attachment(s)
Re: js4vb Javascript Engine w/Debugger and COM
Ok the debugger with UI is usable now..
btw claude says edit and continue is doable! <-- abandoned see below there be dragons
I will look into the jquery parse error, lots of stuff has been moving around. the version i used for testing is in the /tests folder.
one other idea, this combined with the dynproxy code i posted earlier...it may be possible to wrap javascript objects into a COM wrapper to seamlessly access them. This would give us basically native late bound support for json which could be magical..
Attachment 195459
-
Re: js4vb Javascript Engine w/Debugger and COM
Quote:
Originally Posted by
dz32
btw claude says edit and continue is doable!
Well this I gotta see ;) Lack of Edit & Continue is the only thing that has kept me away from using an other Language/IDE as a daily driver.
-
Re: js4vb Javascript Engine w/Debugger and COM
Do you have/keep git repo of this project? It would be entertaining to see history of the progress as its being implemented.
-
Re: js4vb Javascript Engine w/Debugger and COM
Great work.
A small implementation to add objects to the debugger.
ucJSDebugger
Code:
Event AddObject(ByRef inter As CInterpreter)
Public Sub RunScript()
If m_isRunning Then Exit Sub
m_isRunning = True
lblStatus.Caption = "Status: Running..."
UpdateToolbarState
SetToolBarIcons
' lblStatus = "Status: " & IIf(withDebugger, "Debugging...", "Running...")
Set interp = New CInterpreter
RaiseEvent AddObject(interp)
frmDebugger
Code:
Private Sub js_AddObject(inter As CInterpreter)
inter.AddCOMObject "frmDebugger", Me
End Sub
Test
Code:
console.log(frmDebugger.Caption);
frmDebugger.Caption = "workkkkk";
Great work.
-
Re: js4vb Javascript Engine w/Debugger and COM
a public repo isnt a bad idea, im just doing snapshots for now. cleaner an no in between broken states. Im not fancy enough to use a release branch lol
so I am going to abandon the idea of edit and continue. I do not like what its outputting. it wanted to reparse the entire script fresh, keep the old scope and reset to the current line. I see to many problems. When I asked it about only redoing the specific parts, now were into the problem of the intrepreter being entirely ast based on a nasty nested tree structure. If we were running off of a bytecode it would be much easier i think but thats a whole different design than where we started. (reemit a function bytecode then relink it to others)
right now I am working on "Set next statement" will see how that goes.
The idea of exposing AddObject on the debugger form is a great idea. Justed added it to the debugger demo thanks :)
scintinilla also supports intellisense and tooltips so much more to come still...
I think the reason claude can nail the JS implementation so well is that its a very documented design pattern and language with lots of open source implementations. doing things helping to implement the debug UI or set next statement its messing up a lot.
another bonus of having everything done in vb, we have be able to generate a perfect code navigator and refactoring engine.
this is way beyond what i was initially attempting originally i just wanted an ast parser! but cant pass on making the full implementation now..simply must exist!
after set next statement is decent i am going to try to wrap js objects in that dynamic proxy and see what shakes loose.
edit: finished Set next Statement support in code (didnt implement in debugger UI yet thats later)
-
Re: js4vb Javascript Engine w/Debugger and COM
If your curious how we got here and why...
MS Script control lacks debugging support and has an old JS engine syntax (1998 - ES3 spec). I wanted better.
I tried to use the IActiveScript debugger interfaces in VB but it was just brutal and never fully worked right.
http://sandsprite.com/CodeStuff/vbAc...incomplete.zip
Ken Foust had his citrus debugger in C++ but it was still beyond me at the time.
http://sandsprite.com/CodeStuff/CitrusDebugger.7z
Next I was playing with the script basic engine which had a debugger interface
and let me play relatively easily.. I tried bolting on some COM integration. But my additions were rough and crashy. if your scripted anything wrong it was fatal. Debugger control worked great though and was converted to use in process callbacks from C to VB. First script debugger success.
https://sandsprite.com/blogs/index.p...=310&year=2014
Next i found duktape which is a nice small C engine with a debugger protocol (4mb complete with ocx):
https://sandsprite.com/tools.php?id=23
https://sandsprite.com/blogs/index.php?uid=11&pid=343
I again bolted on COM integration which was still a little rough. We had to create JS classes and use a resolver in vb
but I have been using it for years. its a little bulky but wrapped well. Again debugger control was converted to use in process callbacks from C to VB. The bad part was JS does not have true x64 number support which kills me for some of the tasks I have to do :(
So...next came py4vb
https://sandsprite.com/tools.php?id=37
https://sandsprite.com/blogs/index.php?uid=11&pid=534
I was able to rip the pywin32 library and compile it right into python and COM access was seamless!
(Thanks Mark!). It also has debugger capabilities.
You can even do this:
Code:
Dim tmp(), v
tmp = .Eval("[1+2,2,'a', b'test']") 'array containing 3,2,'a', byte array("test")
For Each v In tmp
If IsArray(v) Then
Debug.Print TypeName(v)
Else
Debug.Print v
End If
Next
This is awesome, but now your distributing like 30mb. I dont like how you have to implement the debugger
inside the script layer, dont really like python syntax. The COM integration is first class through.
Dealing with the python runtime from the outside..not my favorite..its a mess in there. Also python is
not really designed well for embedding, total second class use of it. I had to hack the main execution loop
to add an abort and you have to override exit() statements in the script layer to prevent scripts from killing
the host process. Lots of hacky thing going on..
Sooo..thats how we end up here. I have wanted this for literally 25 years!
Targets:
- native vb built for embedding
- seamless com support
- debugger
- full ast access
- full control over all the guts
- full native x64 number support
AI made this the right time to create it I guess. Little late to the party! but...is what it is.
-
Re: js4vb Javascript Engine w/Debugger and COM
Perhaps you can take this approach and let ai generate a C++ Linux basic parser.
-
Re: js4vb Javascript Engine w/Debugger and COM
Soo...this is working now.. (with dynproxy)
Code:
Private Sub Form_Load()
Dim interp As New CInterpreter
If Not ensureDynProxy() Then
MsgBox "DynProxy.dll not found"
Exit Sub
End If
' Create a JavaScript object
interp.Execute "var person = { name: 'John', age: 30, city: 'NYC' };"
' Get it as a VB COM object!
Dim person As Object
Set person = interp.EvalAsObject("person")
' USE IT LIKE A VB OBJECT!
Debug.Print "Name: " & person.name ' "John"
Debug.Print "Age: " & person.age ' 30
Debug.Print "City: " & person.city ' "NYC"
' MODIFY IT!
person.age = 31
person.Job = "Developer" ' Add new property!
' Read BACK via proxy (not JavaScript!)
Debug.Print "Age (read via proxy): " & person.age
Debug.Print "Job (read via proxy): " & person.Job
' CHECK IT IN JAVASCRIPT!
interp.AddCode "console.log('interp.AddCode -> Age: ' + person.age);" ' 31
interp.AddCode "console.log('interp.AddCode -> Job: ' + person.job);" ' "Developer"
' NESTED OBJECTS!
interp.Execute "var company = { name: 'Acme', address: { city: 'Boston', zip: '02101' } };"
Dim Company As Object
Set Company = interp.EvalAsObject("company")
Debug.Print "Company: " & Company.name ' "Acme"
Debug.Print "City: " & Company.address.city ' "Boston"
Debug.Print "Zip: " & Company.address.Zip ' "02101"
'MsgBox "FOR THE GLORY! IT WORKS!", vbExclamation
'output:
'Name: John
'Age: 30
'City: NYC
'Age (read via proxy): 31
'Job (read via proxy): Developer
'interp.AddCode -> Age: 31
'interp.AddCode -> Job: Developer
'Company: Acme
'City: Boston
'Zip: 02101
End Sub
and somehow..this works too..
Code:
interp.Execute "function greet(name) { console.log('Hello, ' + name); return 'Hello, ' + name;}"
Dim greet As Object
Set greet = interp.EvalAsObject("greet")
greet.Invoke "World"
Debug.Print "dbg: " & greet.Call("JavaScript")
Output:
Hello, World
Hello, JavaScript
dbg: Hello, JavaScript
Code:
Dim interp As New CInterpreter
Dim data As Object, items As Variant
'force latebound case - vb ide sucks here..
' maybe trick or firehacker know how to kill case correct in IDE?
Const user = 1, profile = 1, name = 1, email = 1
interp.Execute "var data = {" & _
"items: [1, 2, 3]," & _
"user: {" & _
" profile: {" & _
" name: 'John'," & _
" email: '[email protected]'" & _
" }" & _
"}};"
Set data = interp.EvalAsVariant("data")
Debug.Print "typename(data) = " & TypeName(data) 'Dictionary
Debug.Print data!user!profile!name ' John
Debug.Print data!user!profile!email ' [email protected]
items = data("items")
Debug.Print "typename(items) = " & TypeName(items) 'Variant()
Debug.Print "items(2) = " & items(2) 'items(2) = 3
Debug.Print data("items")(2) '3
'Debug.Print data!items(2) 'error object required
also added support for this keyword..ok arms shot, weekend over....coding bender complete....
-
Re: js4vb Javascript Engine w/Debugger and COM
Quote:
Originally Posted by
dz32
twinbasic ide plugin can enhance TbScript functionality, similar to VBSCRIPT and Js-VBForums
https://www.vbforums.com/showthread.php?911390
-
Re: js4vb Javascript Engine w/Debugger and COM
Someone has written a parser for JS code, and the problem is that it can't perform the parsing of VB code. Microsoft has open sourced the source code for the chakracorejs engine.We are missing the source code for the VBScript parser. The author of another forum topic spent a day making a parser of JS code with ai. If this technology can be used to do VB code parsing, it will run on cross-platform Linux.
-
Re: js4vb Javascript Engine w/Debugger and COM
If possible, convert the parser directly into assembly code. Create exe or DLL in PE format.
Then we have a js6, IDE
It's just like Vb6, you can type in JS code. Visual form design, and finally directly generate an independent winform program.
In fact, the text box button control is calling the API.
If JavaScript can be called. The windows API, that does that.
We are even allowed to execute JS code, VB6 code, at the same time. VB. Net code, VBS code, assembly code, this is a simple script debugger. Add a simple visual form designer. We have invented a new visualization program called IDE. .
At the end of the day, if it runs on the Linux market, it's a cross-platform IDE and compiler.
-
Re: js4vb Javascript Engine w/Debugger and COM
As if a parser is the same as a platform independent compiler..
-
Re: js4vb Javascript Engine w/Debugger and COM
the fun part of this is that we can break standards and make it what we want. couple tweaks so far,
built in alert, prompt, true x64 numbers, print can dump objects and arrays like python, format("my name is {name}") like python and then rolled that into a built in printf
claude offered to add other python nicities like multiple assignments or zip() but I dont want to totally corrupt my js
but the door is wide open for ideas.
I will wrap this into an easy to use dll with simple code examples this weekend. its like 520kb compiled which isnt bad.
-
Re: js4vb Javascript Engine w/Debugger and COM
ok should be pretty good now. compiling as an ActiveX dll with a bunch of simple examples to test it.
-
Re: js4vb Javascript Engine w/Debugger and COM
Great job
A file is missing
Code:
Class=CReference; analysis\CReference.cls
claude.ai is very good, I added small improvements and it worked perfectly, alert, prompt...
keep it up great work
-
Re: js4vb Javascript Engine w/Debugger and COM
oops I will add that back thanks good catch. There should be an alert and prompt added now here are the global functions
Code:
Private Function IsGlobalFunction(funcName As String) As Boolean
Select Case funcName
Case "parseInt", "parseFloat", "isNaN", "isFinite", "isInteger", _
"encodeURIComponent", "decodeURIComponent", "encodeURI", "decodeURI", _
"escape", "unescape", "eval", "print", "alert", "prompt", "format", _
"printf", "hex", "Number", "String"
IsGlobalFunction = True
-
Re: js4vb Javascript Engine w/Debugger and COM
I think something is broken with the console, the messages are not appearing.
The debugger call stack does not work.
Other problem
I get this error when I stop the debugger or close the form.
Variable not set
Code:
Sub Abort()
interp.Abort
End Sub
-
Re: js4vb Javascript Engine w/Debugger and COM
if interp.abort isnt showing up its probably trying to use the old dll, you can open the group project and look at the top of Cinterpreter and ther should be an Abort() function there. If not somethings old. (The new debugger example in examples/5_debugger) try not to mix old and new files as much has changed inside.
Code:
Sub Abort()
m_AbortExec = True
StopDebug
End Sub
Console logging was missing in the debug form, I forgot to add an event handler to raise that event ucJSDebugger add
Code:
Private Sub interp_ConsoleLog(ByVal msg As String)
RaiseEvent output(msg)
End Sub
I will have to hunt on the callstack thing that could take a bit more to find I will update later.
-
Re: js4vb Javascript Engine w/Debugger and COM
ok were back from surgery patient should be healthy..the callstack fix was a little hairy, happened when adding this binding to functions
-
Re: VB6 Javascript ES5 AST Parser / Intrepreter
Quote:
Originally Posted by
dz32
note: for the x64 support you will need utypes.dll its open source:
https://sandsprite.com/tools.php?id=31
i made a design decision to include full x64 signed number support and break specs with traditional js large number but not quite x64 bs
vb6_utypes\class_wrappers
cmdUIntTest_Click ERROR:
Code:
Dim a As New UInt
Dim b As New UInt
List1.Clear
a.use0x = True
b = a.MAX_SIGNED
List1.AddItem "start value: (MAX_SIGNED) " & a
a = a.Add(1)
List1.AddItem "Max+1 signed = " & a
List1.AddItem "Max+1 unsigned = " & a.toString(False)
If b.fromString(a.toString(False)) Then
List1.AddItem "Max+1 signed string transfer = " & b
Else
List1.AddItem "string transfer failed..."
End If
-
Re: VB6 Javascript ES5 AST Parser / Intrepreter
I havent updated those tests in a very very long time. Value was supposed to be the class default property but it looks like it got lost somewhere along the way. I think I used the dll in some places so I cant update it right now. You will have to experiment to figure it out sorry dont have time to go back and fix the examples on that one.
The js4vb.zip linked in the sandsprite blog has the utypes.dll & dynproxy.dll versions I am testing against.
-
Re: js4vb Javascript Engine w/Debugger and COM
DOES IT SUPPORT twinbasic x64 project?
-
Re: js4vb Javascript Engine w/Debugger and COM
I dont use twin basic. I am not sure of its capabilities if it has 64 bit number support or not. That C dll was built to accept vb types and how they map to C types. It may not make any sense to use that dll in twinbasic or not i have no idea.
-
Re: js4vb Javascript Engine w/Debugger and COM
Thanks to @dz for the great work, which has given our VB6 better extensions.
-
Re: js4vb Javascript Engine w/Debugger and COM
Quote:
Originally Posted by
dz32
I dont use twin basic. I am not sure of its capabilities if it has 64 bit number support or not.
TB has LongLong support in 32-bit targets too.
cheers,
</wqw>
-
Re: js4vb Javascript Engine w/Debugger and COM
I've been working with Claude for a bit, until the limit was reached :o.
I've added the Date functions.
In case you are interested and it saves you a limit.
Code:
CParser.cls
Private Function ParseLeftHandSideExpression() As CNode
Dim expr As CNode
If MatchKeyword("new") Then
Set expr = ParseNewExpression()
' ?? ADD: Allow member/call access after 'new'
' Ejemplo: new Date().toString()
Do While match(".") Or match("[") Or match("(")
If match(".") Then
Set expr = ParseStaticMember(expr)
ElseIf match("[") Then
Set expr = ParseComputedMember(expr)
ElseIf match("(") Then
' Convertir a CallExpression si hay ()
Dim callNode As New CNode
callNode.tType = CallExpression_Node
callNode.LineNumber = expr.LineNumber
Set callNode.Callee = expr
Set callNode.Arguments = ParseArguments()
Set expr = callNode
End If
Loop
Else
Set expr = ParseCallExpression()
End If
Set ParseLeftHandSideExpression = expr
End Function
CInterpreter.cls
ADD Date to IsGlobalFunction
Code:
CallGlobalFunction
Case "Date"
' Date() as a function returns string (current date)
result.vType = vtString
result.strVal = Format$(Now, "ddd mmm dd yyyy hh:nn:ss")
in EvaluateNewExpression ADD: Check for Date constructor
Code:
If Node.Callee.tType = Identifier_Node Then
If Node.Callee.Name = "Date" Then
Set result = CreateDateObject(Node.Arguments)
Set EvaluateNewExpression = result
Exit Function
ElseIf Node.Callee.Name = "Error" Then
Code:
' ? ADD new Function CreateDateObject
Private Function CreateDateObject(args As Collection) As CValue
Dim result As New CValue
result.vType = vtObject
Set result.objectProps = New Collection
Set result.objectKeys = New Collection
Dim dateVal As Date
' Determinar la fecha según argumentos
If args.count = 0 Then
' new Date() - fecha actual
dateVal = Now
ElseIf args.count = 1 Then
' new Date(milliseconds) o new Date(dateString)
Dim arg As CNode
Set arg = args(1)
Dim argVal As CValue
Set argVal = EvaluateExpression(arg)
If argVal.vType = vtNumber Then
' Milliseconds desde epoch (simplificado)
dateVal = DateAdd("s", argVal.numVal / 1000, #1/1/1970#)
ElseIf argVal.vType = vtString Then
' Parse date string
On Error Resume Next
dateVal = CDate(argVal.strVal)
If Err.Number <> 0 Then
dateVal = Now ' Fallback
End If
On Error GoTo 0
Else
dateVal = Now
End If
Else
' new Date(year, month, day, hour, min, sec, ms)
' Simplificado - solo year, month, day
Dim yearVal As CValue, monthVal As CValue, dayVal As CValue
Set arg = args(1)
Set yearVal = EvaluateExpression(arg)
Set arg = args(2)
Set monthVal = EvaluateExpression(arg)
Dim day As Long
day = 1
If args.count >= 3 Then
Set arg = args(3)
Set dayVal = EvaluateExpression(arg)
day = CLng(dayVal.ToNumber())
End If
dateVal = DateSerial(CLng(yearVal.ToNumber()), _
CLng(monthVal.ToNumber()) + 1, _
day)
End If
' Agregar métodos del Date object
' toString()
Dim toStringFunc As New CValue
toStringFunc.vType = vtfunction
' Crear función que retorna la fecha como string
Dim toStrFn As New CFunction
toStrFn.Name = "toString"
Set toStrFn.Body = Nothing ' Método nativo
Set toStringFunc.objVal = toStrFn
result.objectProps.Add toStringFunc, "toString"
result.objectKeys.Add "toString", "toString"
' getTime() - milliseconds desde epoch
Dim getTimeFunc As New CValue
getTimeFunc.vType = vtfunction
Dim getTimeFn As New CFunction
getTimeFn.Name = "getTime"
Set getTimeFn.Body = Nothing
Set getTimeFunc.objVal = getTimeFn
result.objectProps.Add getTimeFunc, "getTime"
result.objectKeys.Add "getTime", "getTime"
' Guardar el valor de fecha internamente
Dim internalDate As New CValue
internalDate.vType = vtString
internalDate.strVal = Format$(dateVal, "ddd mmm dd yyyy hh:nn:ss")
result.objectProps.Add internalDate, "_date"
result.objectKeys.Add "_date", "_date"
' Timestamp interno
Dim timestamp As New CValue
timestamp.vType = vtNumber
timestamp.numVal = DateDiff("s", #1/1/1970#, dateVal) * 1000
result.objectProps.Add timestamp, "_timestamp"
result.objectKeys.Add "_timestamp", "_timestamp"
Set CreateDateObject = result
End Function
Code:
inEvaluateCall ADD ElseIf Node.Callee.Object.Name = "Date" Then
' After the section of string methods:
If objVal.vType = vtObject Then
methodName = Node.Callee.prop.Name
' ? ADD: Check for Date methods
If IsDateMethod(methodName) Then
' Evaluate arguments
For i = 1 To Node.Arguments.count
Set arg = Node.Arguments(i)
argValues.add EvaluateExpression(arg)
Next
' Call Date method
Set result = CallDateMethod(objVal, methodName, argValues)
depth = depth - 1
Set EvaluateCall = result
Exit Function
End If
End If
Code:
' ? IsDateMethod,CallDateMethod
Private Function IsDateMethod(methodName As String) As Boolean
Select Case methodName
Case "toString", "toDateString", "toTimeString", _
"getTime", "getFullYear", "getMonth", "getDate", _
"getHours", "getMinutes", "getSeconds", "getMilliseconds"
IsDateMethod = True
Case Else
IsDateMethod = False
End Select
End Function
Private Function CallDateMethod(dateObj As CValue, methodName As String, args As Collection) As CValue
Dim result As New CValue
' Obtener el timestamp interno
Dim timestampVal As CValue
Set timestampVal = dateObj.GetProperty("_timestamp")
If timestampVal Is Nothing Then
result.vType = vtString
result.strVal = "Invalid Date"
Set CallDateMethod = result
Exit Function
End If
' Convertr timestamp to Date VB6
Dim dateVal As Date
dateVal = DateAdd("s", timestampVal.numVal / 1000, #1/1/1970#)
Select Case methodName
Case "toString"
result.vType = vtString
result.strVal = Format$(dateVal, "ddd mmm dd yyyy hh:nn:ss")
Case "toDateString"
result.vType = vtString
result.strVal = Format$(dateVal, "ddd mmm dd yyyy")
Case "toTimeString"
result.vType = vtString
result.strVal = Format$(dateVal, "hh:nn:ss")
Case "getTime"
result.vType = vtNumber
result.numVal = timestampVal.numVal
Case "getFullYear"
result.vType = vtNumber
result.numVal = Year(dateVal)
Case "getMonth"
result.vType = vtNumber
result.numVal = Month(dateVal) - 1 ' JavaScript is 0-based
Case "getDate"
result.vType = vtNumber
result.numVal = Day(dateVal)
Case "getHours"
result.vType = vtNumber
result.numVal = Hour(dateVal)
Case "getMinutes"
result.vType = vtNumber
result.numVal = Minute(dateVal)
Case "getSeconds"
result.vType = vtNumber
result.numVal = Second(dateVal)
Case "getMilliseconds"
result.vType = vtNumber
result.numVal = 0 ' VB6 not have milliseconds
Case Else
result.vType = vtUndefined
End Select
Set CallDateMethod = result
End Function
TEST
Code:
var now = new Date();
print("Current date: " + now.toString());
print("Year: " + now.getFullYear());
print("Month: " + now.getMonth());
print("Day: " + now.getDate());
print("Timestamp: " + now.getTime());
var User= {
name: "Juan",
DateRegistred: new Date().toString()
};
print(JSON.stringify(User, null, 2));
var dateStr = new Date().toString();
print("Date in string: " + dateStr);
-
Re: js4vb Javascript Engine w/Debugger and COM
ok I integrated your date handling and ended up making a public github repo so we can track changes easier.
I also added a static handler for Date.now() and a handler in CValue.ToString() so it doesnt show as [object object]
https://github.com/dzzie/js4vb/blob/...eter.cls#L1661
https://github.com/dzzie/js4vb/blob/...CValue.cls#L84
I added credit for the addition in the git commit log, readme.md and in the date.js test. Thanks for the contribution!
https://github.com/dzzie/js4vb/blob/..._basic/date.js
-
Re: js4vb Javascript Engine w/Debugger and COM
Nothing, it's been more help from claude.ai.
One thing, it wouldn't be good to split the CInterpreter into other modules to avoid overloading it.
For your better understanding.
What's your next step?
Great work.
-
Re: js4vb Javascript Engine w/Debugger and COM
yes it would make sense to go through CIntrepreter and carve out any helpers which did not depend on internal variables it is quite massive. On the upside that is also nice when dealing with AI as everything is accessible at once. I use a code navigator so it is actually still easy to find things: https://www.vbforums.com/showthread....-Addin-for-vb6
honestly I think the project is complete. there will still be some bugs to root out but I dont want my version to get to fancy. I am primarily developing this for embedding in my apps allowing users to script and control them so I dont want it to bloated or big. The fancier the more room for bugs. I do not need a super complete general purpose js engine. just capable.
I have decided not to include regex support at all. If someone needs regex they can use the activex vbscript object which should operate fine.
my next task is probably to take another run at scivb2.ocx for scintinilla support and redo it to clean it up some more.
this project was more of a helper for my other projects than a project in itself.
-
Re: js4vb Javascript Engine w/Debugger and COM
Yes, the project meets the basics of javascript, but I liked the idea of ??adding functions.
I plan to also use it in my apps.
I have added setTimeout, setInterval, clearTimeout, clearInterval, sleep
I have decided to go for the simple thing to do and use event queue.
Sorry I don't know how to use github much
Code:
'CTimerEvent.cls
Option Explicit
Public ID As Long
Public callback As CValue
Public delay As Long
Public IsInterval As Boolean
Public ExecuteAt As Double
Public IsCancelled As Boolean
Code:
'CInterpreter.cls
Private m_timerQueue As Collection
Private m_nextTimerID As Long
IsGlobalFunction ADD
"setTimeout", "setInterval", "clearTimeout", "clearInterval", "sleep"
CallGlobalFunction ADD
Case "sleep"
' sleep(milliseconds) - pausa bloqueante
If args.Count > 0 Then
Set arg = args(1)
Dim ms As Long
ms = CLng(arg.ToNumber())
If ms > 0 And ms < 60000 Then ' Máximo 60 segundos
Sleep ms
DoEvents
End If
End If
result.vType = vtUndefined
Case "setTimeout"
If args.Count >= 2 Then
Set arg = args(1)
If arg.vType = vtfunction Then
Dim delayArg As CValue
Set delayArg = args(2)
ms = CLng(delayArg.ToNumber())
result.vType = vtNumber
result.numVal = ScheduleTimer(arg, ms, False)
Else
result.vType = vtUndefined
End If
Else
result.vType = vtUndefined
End If
Case "setInterval"
If args.Count >= 2 Then
Set arg = args(1)
If arg.vType = vtfunction Then
Set delayArg = args(2)
ms = CLng(delayArg.ToNumber())
result.vType = vtNumber
result.numVal = ScheduleTimer(arg, ms, True)
Else
result.vType = vtUndefined
End If
Else
result.vType = vtUndefined
End If
Case "clearTimeout", "clearInterval"
If args.Count > 0 Then
Set arg = args(1)
Dim timerID As Long
timerID = CLng(arg.ToNumber())
CancelTimer timerID
End If
result.vType = vtUndefined
' .......
Private Sub Class_Initialize()
' ... source ...
Set m_timerQueue = New Collection
m_nextTimerID = 1
End Sub
Private Function ScheduleTimer(callback As CValue, delay As Long, isInterval As Boolean) As Long
Dim evt As New CTimerEvent
evt.ID = m_nextTimerID
m_nextTimerID = m_nextTimerID + 1
Set evt.callback = callback
evt.delay = delay
evt.IsInterval = isInterval
evt.ExecuteAt = Timer + (delay / 1000#)
evt.IsCancelled = False
m_timerQueue.Add evt, "T" & evt.ID
ScheduleTimer = evt.ID
End Function
Private Sub CancelTimer(timerID As Long)
On Error Resume Next
Dim evt As CTimerEvent
Set evt = m_timerQueue("T" & timerID)
If Not evt Is Nothing Then
evt.IsCancelled = True
End If
On Error GoTo 0
End Sub
Public Sub ProcessTimers()
If m_timerQueue.Count = 0 Then Exit Sub
Dim currentTime As Double
currentTime = Timer
Dim evt As CTimerEvent
Dim i As Long
For i = m_timerQueue.Count To 1 Step -1
Set evt = m_timerQueue(i)
If evt.IsCancelled Then
m_timerQueue.Remove i
ElseIf currentTime >= evt.ExecuteAt Then
' Execute callback
On Error Resume Next
If evt.callback.vType = vtfunction Then
Dim emptyArgs As New Collection
CallJSFunction evt.callback, emptyArgs
End If
On Error GoTo 0
If evt.IsInterval And Not evt.IsCancelled Then
evt.ExecuteAt = Timer + (evt.delay / 1000#)
Else
m_timerQueue.Remove i
End If
End If
Next
End Sub
Public Function HasPendingTimers() As Boolean
HasPendingTimers = (m_timerQueue.Count > 0)
End Function
Code:
'modGlobals.bas
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Code:
in vb program
interp.Execute code
Do While interp.HasPendingTimers()
DoEvents
interp.ProcessTimers()
Sleep 10
Loop
TEST
Code:
// ===== TEST 1: sleep() =====
print("start: " + new Date().toString());
//sleep(2000); // 2 seg
print("before 2 seg: " + new Date().toString());
// ===== TEST 2: setTimeout (bloqueante) =====
print("after setTimeout");
setTimeout(function() {
print("after 1 seg");
}, 1000);
// ===== TEST 3: setInterval (con cola) =====
var count = 0;
var intervalID = setInterval(function() {
count++;
print("Tick " + count);
if (count >= 5) {
clearInterval(intervalID);
print("Interval stopped");
}
}, 500);
console.log("intervalID: " + intervalID)
// ===== TEST 4: Callback with closure =====
var message = "hello with closure";
setTimeout(function() {
print(message);
}, 1000);
// ===== TEST 5: Múltiples timers =====
setTimeout(function() { print("Timer 1 (1 seg)"); }, 1000);
setTimeout(function() { print("Timer 2 (2 seg)"); }, 2000);
setTimeout(function() { print("Timer 3 (500ms)"); }, 500);
print("start Timer 4: " + new Date().toString());
setTimeout(function() {
print("Timer 4 (5000ms)");
print("end: " + new Date().toString());
}, 5000);
sorry for my way of speaking, I use a translator
-
Re: js4vb Javascript Engine w/Debugger and COM
those look like good additions. I think others will like them as well. Claude really does a good job of being able to add features it amazes me how well it did building this. Dont forget you can add things with vb classes and AddCOMObject too thats the easiest :)
-
Re: js4vb Javascript Engine w/Debugger and COM
Weekend additions:
- BugFix: for(;;i+=2) compound assignments had endless loop bug
**New Compound Assignments** - `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, `>>>=`
**Bitwise Operators** - `&`, `|`, `^` for regular numbers
**Unsigned Right Shift** - `>>>` and `>>>=` for both Number and Int64
**String.fromCharCode()** - Static method for character code conversion
**Function Constructor** - `new Function()` for dynamic function creation
**Case-Sensitive Keywords** - Proper JavaScript keyword handling (Function vs function)
**Int64 Compound Assignment Refactoring** - Unified handling via `EvaluateInt64Arithmetic`
**Basic audit logging with cancel**
**Operator Coverage:**
- All arithmetic, bitwise, logical, comparison operators
- All assignment and compound assignment operators
- All shift operators including unsigned right shift
- Proper Int64/BigInt auto-promotion
- Boundary case handling (no overflows)
-
Re: js4vb Javascript Engine w/Debugger and COM
random note the COM integration was bruteforcing set obj = callbyname and if the return wasnt an obj, it'd throw an error and then try retVal = callbyname it was horrible, functions getting called twice. Also no more if else cascades based on arg count to CallByName
I ended up having to create a CallByNameEx in C to bypass the slop. downside now dynproxy.dll is required for COM access now
https://github.com/dzzie/js4vb/blob/...proxy.cpp#L751
https://github.com/dzzie/js4vb/blob/...Form1.frm#L108
I will update the zip here when I test it a bit more.
Code:
Dim v As Variant, isObj As Boolean, r As Long, args() As Variant
ReDim args(1)
args(0) = "1"
args(1) = "b"
'no need for set keyword or multiple callbyname if/else based on arg count
r = CallByNameEx(Me, "getme", DISPATCH_METHOD, args, v, isObj)
Function getme(a As Long, b) As Object
Set getme = Me
End Function
Couple more bonuses, com objects could already return a variant array which would auto translate into a js array,
now com objects can also create js engine native types and return them directly into the javascript engine such as
Code:
Function getFunc(IndexVaOrName) 'as CValue of a Json object (or string if we fail!)
Dim ret As CValue, s As String
'{'index':483, 'name':'small_sub_421881', 'start':'0x421881', 'end':'0x4218cf', 'size':'78', 'xrefs':'2', 'refqty':'0', 'argsize':'0', 'tailqty':'0', 'labelqty':'0', 'frsize':'0'}
s = ipc.SendCmdRecvText("getfunc:" & IndexVaOrName & ":" & ipc.listenHwnd)
s = Replace(s, "'", """") 'oopsie
Set ret = json.ParseToCVal(s)
If IsObject(ret) Then
Set getFunc = ret
Else
getFunc = s
End If
End Function
then in the engine CallCOMMethod:
If hr = 0 Then ' S_OK
If isObj Then
If TypeName(resultVar) = "CValue" Then
'caller is returning a JS engine type
Set result = resultVar
Else
result.vType = vtCOMObject
Set result.objVal = resultVar
End If
Else
Set result = VariantToCValue(resultVar)
End If
Else
' Call failed - return undefined
result.vType = vtUndefined
End If
MSScript control is really bad on these fronts. More is possible with python or duktape, but the cross language barrier means it would require mountains of wrapped functions so I just never did it. When everything is in the same language and we can just use COM objects directly it gets super efficient. Real integration benefits to having everything in the same language!
-
Re: js4vb Javascript Engine w/Debugger and COM
Very good work.
To be honest, I've burned through Claude's code.
My project has over 14,000 lines of code.
I couldn't stop adding features XD.
Thanks for being an inspiration.
-
Re: js4vb Javascript Engine w/Debugger and COM
lol i understand completely I have been going through my entire bucket list its amazing what you can get it to kick out.
my only fear is it may turn our brains to jelly and make us very lazy. Actually learning to really really program may die.
-
Re: js4vb Javascript Engine w/Debugger and COM
Could you update the debugger example to use with your new https://github.com/dzzie/sci4vb
-
Re: js4vb Javascript Engine w/Debugger and COM
I added a new debugger example using the new sci4vb ocx. I also had to update the sci4vb I forgot to raiseevent keypressed so the F7 etc would work.
edit: ok updated to use the new sci4vb internal breakpoint management and executing line highlighting
https://github.com/dzzie/js4vb/tree/...s/9_dbg_sci4vb