Metamorphing Machine I rather be this walking metamorphosis
than having that old formed opinion about everything!

Let's build a transpiler! Part 21

This is the twenty-first post in a series of building a transpiler.
You can find the previous ones here.

Last time I said we would parse Events.

We will follow our well-known script: Create a class EventConstruct:

Class EventConstruct
Private Parms_ As Dictionary

Public Name As Token

Private Sub Class_Initialize()
Set Parms_ = New Dictionary
Parms_.CompareMode = vbTextCompare
End Sub

Public Property Get Access() As Accessibility
Access = AccessPublic
End Property

Public Property Get Parameters() As Dictionary
Set Parameters = Parms_
End Property
End Class

Change the Entity class to have Events:

Class Entity
Private Consts_ As Dictionary
Private Enums_ As Dictionary
Private Declares_ As Dictionary
Private Events_ As Dictionary

Public IsClass As Boolean
Public Accessibility As Accessibility
Public Name As Token
Public OptionBase As Integer
Public OptionCompare As VbCompareMethod
Public OptionExplicit As Boolean

Private Sub Class_Initialize()
Set Consts_ = New Dictionary
Consts_.CompareMode = vbTextCompare

Set Enums_ = New Dictionary
Enums_.CompareMode = vbTextCompare

Set Declares_ = New Dictionary
Declares_.CompareMode = vbTextCompare

Set Events_ = New Dictionary
Events_.CompareMode = vbTextCompare
End Sub

Public Property Get Consts() As Dictionary
Set Consts = Consts_
End Property

Public Property Get Enums() As Dictionary
Set Enums = Enums_
End Property

Public Property Get Declares() As Dictionary
Set Declares = Declares_
End Property

Public Property Get Events() As Dictionary
Set Events = Events_
End Property
End Class

Adapt ParseDeclarationArea:

(...)
ElseIf IsKw(Token, vDeclare) Then
ParseDeclare Access, Entity
Access = AccessLocal

ElseIf IsKw(Token, vEvent) Then
If Not Entity.IsClass Then Fail Token, "Event is only valid for Class"
If Access = AccessLocal Then Access = AccessPublic
If Access <> AccessPublic Then Fail Token, "Event can only be Public"
ParseEvent Entity
Access = AccessLocal

ElseIf IsKw(Token, vEnd) Then
Exit Do
(...)

And implement ParseEvent.

Private Sub ParseEvent(ByVal Entity As Entity)
Const RULE = "[Public] Event identifier [([parms])] line_break"
Dim Token As Token
Dim Evt As EventConstruct

Set Token = NextToken
If Not IsProperId(Token) Or Token.Suffix <> vbNullChar Then Fail Token, RULE, "identifier"

Set Evt = New EventConstruct
Set Evt.Name = Token

Set Token = NextToken
If Token.Kind = tkLeftParenthesis Then Set Token = ParseParms(Entity, EventKind, Evt.Parameters)

If Not IsBreak(Token) Then Fail Token, RULE, "line break"
If Entity.Events.Exists(Evt.Name.Text) Then Fail Evt.Name, "Ambiguous name detected: " & Evt.Name.Text
Entity.Events.Add Evt.Name.Text, Evt
End Sub

Next week we'll have a quick detour from our series to teach an old dog a "new" trick.

Andrej Biasic
2020-12-09