Progress on data structures for type sections

Type specifiers will now store a list of members, instead of
type sections doing that. This will make it possible to do an
inline object definition within a data section, = phrase, etc.

The parser will be reworked to include syntax that supports this,
objects and types will be merged into just a type section, and
face sections will have the added capability of defining function
pointer types.
This commit is contained in:
Sasha Koshka 2022-09-09 20:55:03 -04:00
parent cc8ae6c124
commit b3e2d9f822
5 changed files with 129 additions and 73 deletions

View File

@ -1,11 +0,0 @@
package analyzer
func (section TypeSection) Kind () (kind SectionKind) {
kind = SectionKindType
return
}
func (section TypeSection) Name () (name string) {
name = section.name
return
}

View File

@ -2,16 +2,17 @@ package analyzer
import "os"
import "path/filepath"
import "git.tebibyte.media/arf/arf/types"
// import "git.tebibyte.media/arf/arf/types"
import "git.tebibyte.media/arf/arf/parser"
import "git.tebibyte.media/arf/arf/infoerr"
// import "git.tebibyte.media/arf/arf/infoerr"
// AnalysisOperation holds information about an ongoing analysis operation.
type AnalysisOperation struct {
sectionTable SectionTable
modulePath string
trail types.Stack[locator]
currentPosition locator
currentSection parser.Section
}
// Analyze performs a semantic analyisys on the module specified by path, and
@ -78,21 +79,18 @@ func (analyzer *AnalysisOperation) fetchSection (
return
}
// FIXME: this does not take into account, for instance, recursive
// functions or objects that have pointers to themselves.
for _, plate := range analyzer.trail {
if plate == where {
parsedSection.NewError (
"cannot have cyclic section dependency",
infoerr.ErrorKindError)
return
}
}
analyzer.trail.Push(where)
defer analyzer.trail.Pop()
previousPosition := analyzer.currentPosition
previousSection := analyzer.currentSection
analyzer.currentPosition = where
analyzer.currentSection = parsedSection
// TODO: analyze section
// TODO: analyze section. have analysis methods work on currentPosition
// and currentSection.
//
// while building an analyzed section, add it to the section
// table as soon as the vital details are acquired, and mark it as
// incomplete. that way, it can still be referenced by itself in certain
// scenarios.
switch parsedSection.Kind() {
case parser.SectionKindType:
case parser.SectionKindObjt:
@ -102,6 +100,7 @@ func (analyzer *AnalysisOperation) fetchSection (
case parser.SectionKindFunc:
}
analyzer.sectionTable[where] = section
analyzer.currentPosition = previousPosition
analyzer.currentSection = previousSection
return
}
}

View File

@ -2,19 +2,19 @@ package analyzer
// This is a global, cannonical list of primitive and built-in types.
var PrimitiveInt = TypeSection { name: "Int" }
var PrimitiveUInt = TypeSection { name: "UInt" }
var PrimitiveI8 = TypeSection { name: "I8" }
var PrimitiveI16 = TypeSection { name: "I16" }
var PrimitiveI32 = TypeSection { name: "I32" }
var PrimitiveI64 = TypeSection { name: "I64" }
var PrimitiveU8 = TypeSection { name: "U8" }
var PrimitiveU16 = TypeSection { name: "U16" }
var PrimitiveU32 = TypeSection { name: "U32" }
var PrimitiveU64 = TypeSection { name: "U64" }
var PrimitiveInt = TypeSection { sectionBase: sectionBase { name: "Int" } }
var PrimitiveUInt = TypeSection { sectionBase: sectionBase { name: "UInt" } }
var PrimitiveI8 = TypeSection { sectionBase: sectionBase { name: "I8 " } }
var PrimitiveI16 = TypeSection { sectionBase: sectionBase { name: "I16 " } }
var PrimitiveI32 = TypeSection { sectionBase: sectionBase { name: "I32 " } }
var PrimitiveI64 = TypeSection { sectionBase: sectionBase { name: "I64 " } }
var PrimitiveU8 = TypeSection { sectionBase: sectionBase { name: "U8 " } }
var PrimitiveU16 = TypeSection { sectionBase: sectionBase { name: "U16 " } }
var PrimitiveU32 = TypeSection { sectionBase: sectionBase { name: "U32 " } }
var PrimitiveU64 = TypeSection { sectionBase: sectionBase { name: "U64 " } }
var PrimitiveObjt = TypeSection { name: "Objt" }
var PrimitiveFace = TypeSection { name: "Face" }
var PrimitiveObjt = TypeSection { sectionBase: sectionBase { name: "Objt" } }
var PrimitiveFace = TypeSection { sectionBase: sectionBase { name: "Face" } }
var BuiltInString = TypeSection {
inherits: Type {

View File

@ -24,38 +24,26 @@ const (
// Section is a semantically analyzed section.
type Section interface {
Kind () (kind SectionKind)
Name () (name string)
ToString () (output string)
Kind () (kind SectionKind)
Name () (name string)
ToString (indent int) (output string)
Complete () (complete bool)
}
// TypeKind represents what kind of type a type is.
type TypeKind int
const (
// TypeKindBasic means it's a single value, or a fixed length array.
TypeKindBasic TypeKind = iota
// TypeKindPointer means it's a pointer
TypeKindPointer
// TypeKindVariableArray means it's an array of variable length.
TypeKindVariableArray
)
// Type represents a description of a type. It must eventually point to a
// TypeSection.
type Type struct {
actual Section
points *Type
mutable bool
kind TypeKind
length uint64
}
// TypeSection represents a type definition section.
type TypeSection struct {
// sectionBase is a struct that all sections must embed.
type sectionBase struct {
name string
inherits Type
complete bool
}
// Name returns the name of the section.
func (section sectionBase) Name () (name string) {
name = section.name
return
}
// Complete returns wether the section has been completed.
func (section sectionBase) Complete () (complete bool) {
complete = section.complete
return
}

80
analyzer/type.go Normal file
View File

@ -0,0 +1,80 @@
package analyzer
import "fmt"
import "git.tebibyte.media/arf/arf/types"
// TypeKind represents what kind of type a type is.
type TypeKind int
const (
// TypeKindBasic means it's a single value.
TypeKindBasic TypeKind = iota
// TypeKindPointer means it's a pointer
TypeKindPointer
// TypeKindVariableArray means it's an array of variable length.
TypeKindVariableArray
// TypeKindObject means it's a structured type with members.
TypeKindObject
)
// ObjectMember is a member of an object type.
type ObjectMember struct {
name string
// even if there is a private permission in another module, we still
// need to include it in the semantic analysis because we need to know
// how many members objects have.
permission types.Permission
// TODO: create argument type similar to what's in the parser and have
// a defaultValue member here.
}
// Type represents a description of a type. It must eventually point to a
// TypeSection.
type Type struct {
actual Section
points *Type
mutable bool
kind TypeKind
// if this is greater than 1, it means that this is a fixed-length array
// of whatever the type is. even if the type is a variable length array.
// because literally why not.
length uint64
// this is only applicable for a TypeKindObject where new members are
// defined.
// TODO: do not add members from parent type. instead have a member
// function to discern whether this type contains a particular member,
// and have it recurse all the way up the family tree. it will be the
// translator's job to worry about what members are placed where.
members []ObjectMember
}
// ToString returns all data stored within the type, in string form.
func (what Type) ToString (indent int) (output string) {
output += fmt.Sprint("")
return
}
// TypeSection represents a type definition section.
type TypeSection struct {
sectionBase
inherits Type
}
// Kind returns SectionKindType.
func (section TypeSection) Kind () (kind SectionKind) {
kind = SectionKindType
return
}
// ToString returns all data stored within the type section, in string form.
func (section TypeSection) ToString (indent int) (output string) {
return
}