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

Let's build a transpiler! Part 26

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

(In an attempt to make this post a little more professional, I'll be following the suggestions taken from this site.)
Last time I said we would parse Types.

We will take advantage benefit of ParseDim as many of what it does is what we need.
The difference distinction is that it will accept three things matters that are now not allowed in Types: We'll try to deal with these situations conditions in the code below:

Public Class TypeConstruct
Option Explicit

Private Members_ As KeyedList

Public Access As Accessibility
Public Id As Identifier

Private Sub Class_Initialize()
Set Members_ = New KeyedList
Members_.CompareMode = vbTextCompare
End Sub

Public Property Get Members() As KeyedList
Set Members = Members_
End Property
End Class


Rem Additions to Entity class
Public Class Entity
Private Types_ As KeyedList
(...)
Private Sub Class_Initialize()
(...)
Set Types_ = New KeyedList
Types_.CompareMode = vbTextCompare
End Sub
(...)
Public Property Get Types() As KeyedList
Set Types = Types_
End Property
End Class


Rem Addition to ParseDeclarationArea
Private Function ParseDeclarationArea(ByVal Entity As Entity) As Token
(...)
Case kwType
If Access = AccessLocal Then Access = AccessPublic
ParseType Access, Entity
Access = AccessLocal
(...)
End Function


Rem Addition to Parse class
Private Sub ParseType(ByVal Access As Accessibility, ByVal Entity As Entity)
Dim Name As String
Dim Token As Token
Dim Ent As Entity
Dim Var As Variable
Dim Typ As TypeConstruct

Set Ent = New Entity
Set Typ = New TypeConstruct
Typ.Access = Access

Set Token = NextToken
If Not IsProperId(Token) Then Fail Token, Msg066, Msg003

Set Typ.Id = NewId(Token)
MustEatLineBreak
Set Token = Nothing 'Force ParseDim to get next token

Do
ParseDim AccessLocal, Ent, Token:=Token
Rem Should not have "A As Boolean, B As ...
If Ent.Vars.Count > 1 Then Fail Ent.Vars(2).Id.Name, Msg067, Msg031

Set Var = Ent.Vars(1)
Rem Must have an explicit data type.
If Var.DataType.Id.Name.Line = 0 Then Fail Var.DataType.Id.Name, Msg067, vAs

Rem Must not have an initial value.
If Not Var.Init Is Nothing Then Fail Var.Init, Msg067, Msg031

Ent.Vars.Clear
Name = NameOf(Var.Id.Name)
If Typ.Members.Exists(Name) Then Fail Var.Id.Name, Msg006 & Name

Typ.Members.Add Var, Name
Set Token = SkipLineBreaks
Loop Until IsKw(Token, kwEnd)

Set Token = NextToken
If Not IsKw(Token, kwType) Then Fail Token, Msg068, vType

Name = NameOf(Typ.Id.Name)
If Entity.Types.Exists(Name) Then Fail Typ.Id.Name, Msg006 & NameOf(Var.Id.Name)
Entity.Types.Add Typ, Name
End Sub


Rem Addition to Messages module
Public Property Get Msg066() As String
Msg066 = "Rule: [Public | Private] Enum identifier"
End Property

Public Property Get Msg067() As String
Msg067 = "Rule: member_name As data_type"
End Property

Public Property Get Msg068() As String
Msg068 = "Rule: End Type"
End Property

And having completed done that, we are done performed parsing the declaration statement area.
Next week we'll we are going to have a break ruin from our transpiler series collection to talk discuss... nothing.

(Hmm... Maybe it'd be better to get over this "professional" thing...)

Andrej Biasic
2021-02-17