diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index 7beb987..7c90066 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -63,6 +63,9 @@ func (analyzer *AnalysisOperation) fetchSection ( err error, ) { var exists bool + section, exists = analyzer.resolvePrimitive(where) + if exists { return } + section, exists = analyzer.sectionTable[where] if exists { return } @@ -156,6 +159,45 @@ func (analyzer *AnalysisOperation) fetchSectionFromIdentifier ( return } +// resolvePrimitive checks to see if the locator is in the current module, and +// refers to a primitive. If it does, it returns a pointer to that primitive +// and true for exists. If it doesn't, it returns nil and false. +func (analyzer *AnalysisOperation) resolvePrimitive ( + where locator, +) ( + section Section, + exists bool, +) { + // primitives are scoped as if they are contained within the current + // module, so if the location refers to something outside of the current + // module, it is definetly not referring to a primitive. + if where.modulePath != analyzer.currentPosition.modulePath { + return + } + + exists = true + switch where.name { + case "Int": section = &PrimitiveInt + case "UInt": section = &PrimitiveUInt + case "I8": section = &PrimitiveI8 + case "I16": section = &PrimitiveI16 + case "I32": section = &PrimitiveI32 + case "I64": section = &PrimitiveI64 + case "U8": section = &PrimitiveU8 + case "U16": section = &PrimitiveU16 + case "U32": section = &PrimitiveU32 + case "U64": section = &PrimitiveU64 + case "Objt": section = &PrimitiveObjt + case "Face": section = &PrimitiveFace + case "Func": section = &PrimitiveFunc + case "String": section = &BuiltInString + default: + exists = false + } + + return +} + // addSection adds a section to the analyzer's section table. If a section with // that name already exists, it panics because the parser should not have given // that to us. diff --git a/analyzer/argument.go b/analyzer/argument.go index 654c731..15553f6 100644 --- a/analyzer/argument.go +++ b/analyzer/argument.go @@ -26,6 +26,7 @@ func (analyzer AnalysisOperation) analyzeArgument ( inputArgument parser.Argument, ) ( outputArgument Argument, + err error, ) { switch inputArgument.Kind() { case parser.ArgumentKindNil: diff --git a/analyzer/primitives.go b/analyzer/primitives.go index 7148d3a..adf2a2f 100644 --- a/analyzer/primitives.go +++ b/analyzer/primitives.go @@ -14,6 +14,7 @@ var PrimitiveU32 = createPrimitive("U32", Type {}) var PrimitiveU64 = createPrimitive("U64", Type {}) var PrimitiveObjt = createPrimitive("Objt", Type {}) var PrimitiveFace = createPrimitive("Face", Type {}) +var PrimitiveFunc = createPrimitive("Func", Type {}) var BuiltInString = createPrimitive("String", Type { actual: PrimitiveU32, diff --git a/analyzer/type-section.go b/analyzer/type-section.go index 80e8aa3..e40d1ce 100644 --- a/analyzer/type-section.go +++ b/analyzer/type-section.go @@ -9,6 +9,7 @@ type TypeSection struct { sectionBase what Type complete bool + argument Argument // 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 @@ -42,6 +43,9 @@ func (member ObjectMember) ToString (indent int) (output string) { func (section TypeSection) ToString (indent int) (output string) { output += doIndent(indent, "typeSection ", section.where.ToString(), "\n") output += section.what.ToString(indent + 1) + if section.argument != nil { + output += section.argument.ToString(indent + 1) + } return } @@ -66,7 +70,15 @@ func (analyzer AnalysisOperation) analyzeTypeSection () ( outputSection.what, err = analyzer.analyzeType(inputSection.Type()) if err != nil { return } - + + if !inputSection.Argument().Nil() { + outputSection.argument, + err = analyzer.analyzeArgument(inputSection.Argument()) + if err != nil { return } + // TODO: type check default value. possibly add a method to + // Argument that takes in a type and determines whether the + // argument can fit to it. + } // TODO: analyze members diff --git a/analyzer/type-section_test.go b/analyzer/type-section_test.go index af7174c..afdbab5 100644 --- a/analyzer/type-section_test.go +++ b/analyzer/type-section_test.go @@ -6,5 +6,6 @@ func TestTypeSection (test *testing.T) { checkTree ("../tests/analyzer/typeSection", false, `typeSection ../tests/analyzer/typeSection.basicInt type 1 basic Int + arg uint 5 `, test) } diff --git a/analyzer/type.go b/analyzer/type.go index f7784eb..1ad90b6 100644 --- a/analyzer/type.go +++ b/analyzer/type.go @@ -63,8 +63,10 @@ func (what Type) ToString (indent int) (output string) { } if what.actual != nil { - output += what.actual.Name() + output += " " + what.actual.Name() } + + output += "\n" return } diff --git a/parser/accessors.go b/parser/accessors.go index bff9d95..acfef7d 100644 --- a/parser/accessors.go +++ b/parser/accessors.go @@ -115,6 +115,12 @@ func (argument Argument) Kind () (kind ArgumentKind) { return } +// Nil returns true if the argument is nil, and false if it isn't. +func (argument Argument) Nil () (isNil bool) { + isNil = argument.kind == ArgumentKindNil + return +} + // Value returns the underlying value of the argument. You can use Kind() to // find out what to cast this to. func (argument Argument) Value () (value any) {