diff --git a/analyzer/accessors.go b/analyzer/accessors.go deleted file mode 100644 index 12cd52d..0000000 --- a/analyzer/accessors.go +++ /dev/null @@ -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 -} diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index c5f4abe..eeccaa0 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -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 -} +} diff --git a/analyzer/primitives.go b/analyzer/primitives.go index 92ffc26..b92f92d 100644 --- a/analyzer/primitives.go +++ b/analyzer/primitives.go @@ -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 { diff --git a/analyzer/table.go b/analyzer/table.go index 01f6418..478cdac 100644 --- a/analyzer/table.go +++ b/analyzer/table.go @@ -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 } diff --git a/analyzer/type.go b/analyzer/type.go new file mode 100644 index 0000000..0c354f8 --- /dev/null +++ b/analyzer/type.go @@ -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 +}