Created
September 19, 2021 12:27
-
-
Save GWRon/681d58b710c6fecaebfb2a6e97ad5d8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SuperStrict | |
Framework Brl.StandardIO | |
Import Pub.FreeProcess | |
Import MaxGUI.Drivers | |
Import Brl.EventQueue | |
Import Brl.Bank | |
Import "lexer/Lexer.bmx" | |
Import "parser/Parser.bmx" | |
New TApp.Run() | |
Type TApp | |
Field guiWindow:TGadget | |
Field guiTreeview:TGadget | |
Field guiTreeviewRoot:TGadget | |
Field guiTextarea:TGadget | |
Field codeLineStartIndices:int[] | |
Field codeLineEndIndices:int[] | |
Field codeContent:String | |
Method InitGUI() | |
guiWindow:TGadget = CreateWindow("TreeVisualizer", 100, 100, 800, 400, Null) ', WINDOW_TITLEBAR | WINDOW_STATUS) | |
guiTextarea = CreateTextArea(0, 0, ClientWidth(guiWindow) / 2 - 5,ClientHeight(guiWindow), guiWindow, TEXTAREA_READONLY) | |
'pin to corners | |
SetGadgetLayout(guiTextArea, EDGE_ALIGNED, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_ALIGNED) | |
guiTreeview:TGadget = CreateTreeView(ClientWidth(guiWindow) / 2 + 5, 0, ClientWidth(guiWindow) / 2 - 5, ClientHeight(guiWindow), guiWindow) | |
'pin to corners | |
SetGadgetLayout(guiTreeview, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED) | |
guiTreeviewRoot = TreeViewRoot(guiTreeview) | |
End Method | |
Method ProcessFile:String(uri:String) | |
Local fileURI:String = CurrentDir() + "/" + uri | |
codeContent = LoadFileContent(fileURI) | |
'cache line start/ending (so also length) information | |
Local lines:String[] = codeContent.Split("~n") | |
codeLineStartIndices = new Int[lines.length] | |
codeLineEndIndices = new Int[lines.length] | |
Local lastIndex:int = 0 | |
for local i:int = 0 until lines.length | |
codeLineStartIndices[i] = lastIndex | |
codeLineEndIndices[i] = lastIndex + lines[i].length + 1 'add back newline | |
lastIndex = codeLineEndIndices[i] | |
'print "line "+i+" = " + codeLineStartIndices[i] +" - " + codeLineEndIndices[i] + " = ~q" + codeContent[codeLineStartIndices[i] .. codeLineEndIndices[i]] +"~q" | |
Next | |
SetTextAreaText( guiTextArea, codeContent, 0, TEXTAREA_ALL, TEXTAREA_CHARS) | |
Local parser:IParser = New TParser(New TLexer(fileURI)) | |
Local x:ISyntax = parser.ParseCompilationUnit() | |
'handle errors | |
'rem | |
For Local error:TParseError = EachIn parser.Errors() | |
Print "PARSE ERROR: " + error.ToString() | |
Notify "PARSE ERROR: " + error.ToString() | |
Next | |
'endrem | |
AppendNode(x, True, guiTreeviewRoot) | |
Function AppendNode(o:Object, showMinorFields:Int, parentNode:TGadget, prependText:String = "") | |
Local t:TTypeId = TTypeId.ForObject(o) | |
If Not o | |
Return | |
ElseIf ISyntax(o) | |
Local syntax:ISyntax = ISyntax(o) | |
Local codeRange:SCodeRange = ISyntax(o).CodeRange() | |
Local lineInfo:String = " ["+codeRange.startLocation.line+":"+codeRange.startLocation.column+"]" | |
Local label:String = t.Name() | |
if prependText then label = prependText + ": " + label + lineInfo | |
Local node:TGadget = AddTreeViewNode(label, parentNode, -1, o) | |
For Local f:TField = EachIn GetAllFields(t) | |
If Not showMinorFields And f.MetaData("minor") Then Continue | |
Local fValue:Object = f.Get(syntax) | |
AppendNode(fValue, showMinorFields, node, f.Name()) | |
Next | |
ElseIf t.ExtendsType(ArrayTypeId) | |
If t.Name() = "Null[]" Then Return | |
'1) fieldname:typename[] ? | |
'Local label:String = t.Name() | |
'if prependText then label = prependText + ": " + label | |
'2) fieldname | |
Local label:String = prependText | |
Local node:TGadget = AddTreeViewNode(label, parentNode, -1, o) | |
For Local i:Int = 0 Until t.ArrayLength(o) | |
AppendNode(t.GetArrayElement(o, i), showMinorFields, node) | |
Next | |
ElseIf TSyntaxToken(o) | |
Local codeRange:SCodeRange = TSyntaxToken(o).lexerToken.CodeRange() | |
Local lineInfo:String = " ["+codeRange.startLocation.line+":"+codeRange.startLocation.column+"]" | |
AddTreeViewNode(o.ToString() + lineInfo, parentNode, -1, o) | |
Else | |
AddTreeViewNode(o.ToString(), parentNode, -1, o) | |
End If | |
End Function | |
End Method | |
Function LoadFileContent:String(url:Object) | |
'source: http://sodaware.sdf.org/blog/blitzmax-file-loading/ | |
'ensure finishing with 0 byte | |
Local bank:TBank = LoadBank(url) | |
bank.Resize(bank.size() + 1) | |
PokeByte(bank, bank.size() - 1, 0) | |
Local buffer:Byte Ptr = LockBank(bank) | |
Local content:String = String.FromCString(buffer) | |
UnlockBank(bank) | |
Return content | |
End Function | |
Method OnClickTreeView() | |
If Not guiTreeview.SelectedNode() Then Return | |
local syntaxOrToken:ISyntaxOrSyntaxToken = ISyntaxOrSyntaxToken(guiTreeview.SelectedNode().extra) | |
if not syntaxOrToken Then Return | |
Local codeRange:SCodeRange = syntaxOrToken.CodeRange() | |
if not codeRange.IsValid() Then Return | |
Local startIndex:Int = codeLineStartIndices[codeRange.startLocation.line - 1] + (codeRange.startLocation.column - 1) | |
Local endIndex:Int = codeLineStartIndices[codeRange.endLocation.line - 1] + (codeRange.endLocation.column - 1) | |
print "code " + startIndex + " - " + endIndex + " ["+codeRange.startLocation.line+":"+codeRange.startLocation.column+"] - ["+codeRange.endLocation.line+":"+codeRange.endLocation.column+"]" + " = ~q" + codeContent[startIndex .. endIndex] +"~q" | |
'select | |
guiTextArea.SetSelection(startIndex, endIndex - startIndex, TEXTAREA_CHARS) | |
End Method | |
Method Run() | |
InitGUI() | |
ProcessFile("samples/test.bmx") | |
Repeat | |
Select WaitEvent() | |
Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE | |
End | |
Case EVENT_GADGETSELECT | |
'select something on tree view | |
if EventSource() = guiTreeview | |
OnClickTreeView() | |
endif | |
Case EVENT_GADGETACTION | |
'double click on tree view | |
'if EventSource() = guiTreeview | |
' OnClickTreeView() | |
'endif | |
EndSelect | |
Forever | |
End Method | |
End Type |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment