Im gonna have to rewrite this whole compiler arent i
This commit is contained in:
parent
c13c4caacb
commit
1d1908cd5d
|
@ -96,9 +96,9 @@ func (this *generator) generateAssignmentToDestination ( // TODO: add -Val suffi
|
|||
destTypeBase, irDestLoc,
|
||||
irDestType, name)
|
||||
key := entity.Key {
|
||||
Unit: sourceType.Unit(),
|
||||
Name: sourceType.Name,
|
||||
Method: name,
|
||||
Unit: sourceType.Unit(),
|
||||
Type: sourceType.Name,
|
||||
Function: name,
|
||||
}
|
||||
fromBehavior, err := this.method(key)
|
||||
if err != nil { return nil, err }
|
||||
|
@ -124,9 +124,9 @@ func (this *generator) generateAssignmentToDestination ( // TODO: add -Val suffi
|
|||
destTypeBase, irDestLoc,
|
||||
irDestType, name)
|
||||
key := entity.Key {
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Name: sourceType.Name,
|
||||
Method: name,
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Type: sourceType.Name,
|
||||
Function: name,
|
||||
}
|
||||
fromBehavior, err := this.method(key)
|
||||
if err != nil { return nil, err }
|
||||
|
|
|
@ -28,15 +28,15 @@ func (this *generator) generateConstantFloat (literal *entity.LiteralFloat) (llv
|
|||
}
|
||||
|
||||
func (this *generator) generateConstantString (literal *entity.LiteralString) (llvm.Const, error) {
|
||||
|
||||
panic("BUG: not supported yet")
|
||||
}
|
||||
|
||||
func (this *generator) generateConstantArray (literal *entity.LiteralArray) (llvm.Const, error) {
|
||||
|
||||
panic("BUG: not supported yet")
|
||||
}
|
||||
|
||||
func (this *generator) generateConstantStruct (literal *entity.LiteralStruct) (llvm.Const, error) {
|
||||
|
||||
panic("BUG: not supported yet")
|
||||
}
|
||||
|
||||
func (this *generator) generateConstantBoolean (literal *entity.LiteralBoolean) (llvm.Const, error) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package generator
|
||||
|
||||
import "git.tebibyte.media/fspl/fspl/llvm"
|
||||
import "git.tebibyte.media/fspl/fspl/entity"
|
||||
|
||||
func (this *generator) generateConstantDeclaration (
|
||||
ty *entity.Typedef,
|
||||
constantName string,
|
||||
) (
|
||||
*llvm.Global,
|
||||
error,
|
||||
) {
|
||||
key := entity.Key {
|
||||
Unit: ty.Unit(),
|
||||
Type: ty.Name,
|
||||
Constant: constantName,
|
||||
}
|
||||
constant := ty.ConstantMap[constantName]
|
||||
|
||||
irType, err := this.typedef(key.OnlyType())
|
||||
if err != nil { return nil, err }
|
||||
|
||||
irGlobal := this.module.NewGlobal(constantName, irType)
|
||||
irGlobal.Constant = true
|
||||
|
||||
if ty.Unit() == this.tree.Unit() {
|
||||
// in root unit, so generate data
|
||||
initial, err := this.generateConstant(constant.Value)
|
||||
if err != nil { return nil, err }
|
||||
irGlobal.Initial = initial
|
||||
}
|
||||
|
||||
this.constants[key] = irGlobal
|
||||
return irGlobal, nil
|
||||
}
|
|
@ -67,8 +67,7 @@ func (this *generator) generateExpressionAny (expression entity.Expression) (reg
|
|||
*entity.LiteralString,
|
||||
*entity.LiteralStruct,
|
||||
*entity.Variable,
|
||||
*entity.Declaration,
|
||||
*entity.Constant:
|
||||
*entity.Declaration:
|
||||
|
||||
pointer, err := this.generateExpressionLoc(expression)
|
||||
return pointer, true, err
|
||||
|
@ -133,8 +132,7 @@ func (this *generator) generateExpressionVal (expression entity.Expression) (llv
|
|||
*entity.LiteralString,
|
||||
*entity.LiteralStruct,
|
||||
*entity.Variable,
|
||||
*entity.Declaration,
|
||||
*entity.Constant:
|
||||
*entity.Declaration:
|
||||
|
||||
pointer, err := this.generateExpressionLoc(expression)
|
||||
if err != nil { return nil, err }
|
||||
|
@ -251,8 +249,6 @@ func (this *generator) generateExpressionLoc (expression entity.Expression) (llv
|
|||
case *entity.For:
|
||||
loc, _, err := this.generateFor(expression, resultModeLoc)
|
||||
return loc, err
|
||||
case *entity.Constant:
|
||||
return this.generateConstantLoc(expression)
|
||||
case *entity.LiteralArray:
|
||||
return this.generateLiteralArrayLoc(expression, nil)
|
||||
case *entity.LiteralString:
|
||||
|
|
|
@ -8,8 +8,8 @@ import "git.tebibyte.media/fspl/fspl/analyzer"
|
|||
|
||||
func (this *generator) generateCallVal (call *entity.Call) (llvm.Value, error) {
|
||||
function, err := this.function(entity.Key {
|
||||
Unit: call.Unit,
|
||||
Name: call.Name,
|
||||
Unit: call.Unit,
|
||||
Function: call.Name,
|
||||
})
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
@ -45,9 +45,9 @@ func (this *generator) generateMethodCallVal (call *entity.MethodCall) (llvm.Val
|
|||
// check for methods on named type
|
||||
if sourceType, ok := call.Source.Type().(*entity.TypeNamed); ok {
|
||||
methodKey := entity.Key {
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Name: sourceType.Name,
|
||||
Method: call.Name,
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Type: sourceType.Name,
|
||||
Function: call.Name,
|
||||
}
|
||||
method, err := this.method(methodKey)
|
||||
if _, notFound := err.(errNotFound); !notFound {
|
||||
|
@ -62,9 +62,9 @@ func (this *generator) generateMethodCallVal (call *entity.MethodCall) (llvm.Val
|
|||
if pointerType, ok := call.Source.Type().(*entity.TypePointer); ok {
|
||||
if sourceType, ok := pointerType.Referenced.(*entity.TypeNamed); ok {
|
||||
method, err := this.method(entity.Key {
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Name: sourceType.Name,
|
||||
Method: call.Name,
|
||||
Unit: sourceType.Type.Unit(),
|
||||
Type: sourceType.Name,
|
||||
Function: call.Name,
|
||||
})
|
||||
if _, notFound := err.(errNotFound); !notFound {
|
||||
source, err := this.generateExpressionVal(call.Source)
|
||||
|
|
|
@ -10,8 +10,8 @@ func (this *generator) generateFunction (
|
|||
error,
|
||||
) {
|
||||
key := entity.Key {
|
||||
Unit: function.Unit(),
|
||||
Name: function.Signature.Name,
|
||||
Unit: function.Unit(),
|
||||
Function: function.Signature.Name,
|
||||
}
|
||||
|
||||
params := make([]*llvm.Parameter, len(function.Signature.Arguments))
|
||||
|
@ -60,9 +60,9 @@ func (this *generator) generateMethod (
|
|||
error,
|
||||
) {
|
||||
key := entity.Key {
|
||||
Unit: method.Unit(),
|
||||
Name: method.TypeName,
|
||||
Method: method.Signature.Name,
|
||||
Unit: method.Unit(),
|
||||
Type: method.TypeName,
|
||||
Function: method.Signature.Name,
|
||||
}
|
||||
|
||||
params := make([]*llvm.Parameter, len(method.Signature.Arguments) + 1)
|
||||
|
|
|
@ -30,10 +30,9 @@ type generator struct {
|
|||
tree analyzer.Tree
|
||||
module *llvm.Module
|
||||
|
||||
types map[entity.Key] llvm.Type
|
||||
functions map[entity.Key] *llvm.Function
|
||||
constantsVal map[entity.Key] llvm.Value
|
||||
constantsLoc map[entity.Key] llvm.Value
|
||||
types map[entity.Key] llvm.Type
|
||||
functions map[entity.Key] *llvm.Function
|
||||
constants map[entity.Key] *llvm.Global
|
||||
|
||||
managerStack []*blockManager
|
||||
blockManager *blockManager
|
||||
|
@ -47,31 +46,41 @@ func (this Target) Generate (tree analyzer.Tree) (*llvm.Module, error) {
|
|||
module: new(llvm.Module),
|
||||
target: this,
|
||||
tree: tree,
|
||||
types: make(map[entity.Key] llvm.Type),
|
||||
functions: make(map[entity.Key] *llvm.Function),
|
||||
constantsVal: make(map[entity.Key] llvm.Value),
|
||||
constantsLoc: make(map[entity.Key] llvm.Value),
|
||||
types: make(map[entity.Key] llvm.Type),
|
||||
functions: make(map[entity.Key] *llvm.Function),
|
||||
constants: make(map[entity.Key] *llvm.Global),
|
||||
}).generate()
|
||||
}
|
||||
|
||||
func (this *generator) generate () (*llvm.Module, error) {
|
||||
// TODO: generate constants here
|
||||
functions := sortKeyedMapKeys(this.tree.Functions)
|
||||
types := sortKeyedMapKeys(this.tree.Types)
|
||||
|
||||
// generate constants
|
||||
for _, key := range types {
|
||||
ty := this.tree.Types[key]
|
||||
constants := sortMapKeys(ty.ConstantMap)
|
||||
for _, constantName := range constants {
|
||||
constantKey := key
|
||||
constantKey.Constant = constantName
|
||||
_, err := this.constant(constantKey)
|
||||
if err != nil { return nil, err }
|
||||
}
|
||||
}
|
||||
|
||||
// generate functions
|
||||
functions := sortKeyedMapKeys(this.tree.Functions)
|
||||
for _, key := range functions {
|
||||
_, err := this.function(key)
|
||||
if err != nil { return nil, err }
|
||||
}
|
||||
|
||||
// generate methods
|
||||
types := sortKeyedMapKeys(this.tree.Types)
|
||||
for _, key := range types {
|
||||
ty := this.tree.Types[key]
|
||||
methods := sortMapKeys(ty.Methods)
|
||||
for _, methodName := range methods {
|
||||
methodKey := key
|
||||
methodKey.Method = methodName
|
||||
methodKey.Function = methodName
|
||||
_, err := this.method(methodKey)
|
||||
if err != nil { return nil, err }
|
||||
}
|
||||
|
@ -91,16 +100,31 @@ func (this *generator) typedef (key entity.Key) (llvm.Type, error) {
|
|||
return this.generateTypedef(def)
|
||||
}
|
||||
|
||||
func (this *generator) method (key entity.Key) (*llvm.Function, error) {
|
||||
method, exists := this.functions[key]
|
||||
if exists { return method, nil }
|
||||
func (this *generator) constant (key entity.Key) (*llvm.Global, error) {
|
||||
constant, exists := this.constants[key]
|
||||
if exists { return constant, nil }
|
||||
|
||||
ty, exists := this.tree.Types[key.StripMethod()]
|
||||
ty, exists := this.tree.Types[key.OnlyType()]
|
||||
if !exists {
|
||||
return nil, errNotFound("owner of method " + key.String())
|
||||
}
|
||||
|
||||
if method, exists := ty.Methods[key.Method]; exists {
|
||||
if _, exists := ty.ConstantMap[key.Constant]; exists {
|
||||
return this.generateConstantDeclaration(ty, key.Constant)
|
||||
}
|
||||
return nil, errNotFound("constant " + key.String())
|
||||
}
|
||||
|
||||
func (this *generator) method (key entity.Key) (*llvm.Function, error) {
|
||||
method, exists := this.functions[key]
|
||||
if exists { return method, nil }
|
||||
|
||||
ty, exists := this.tree.Types[key.OnlyType()]
|
||||
if !exists {
|
||||
return nil, errNotFound("owner of method " + key.String())
|
||||
}
|
||||
|
||||
if method, exists := ty.Methods[key.Function]; exists {
|
||||
return this.generateMethod(method)
|
||||
}
|
||||
return nil, errNotFound("method " + key.String())
|
||||
|
|
|
@ -12,7 +12,7 @@ func (this *generator) generateTypedef (
|
|||
) {
|
||||
key := entity.Key {
|
||||
Unit: def.Unit(),
|
||||
Name: def.Name,
|
||||
Type: def.Name,
|
||||
}
|
||||
irType, err := this.generateType(def.Type)
|
||||
if err != nil { return nil, err }
|
||||
|
|
|
@ -8,7 +8,7 @@ import "git.tebibyte.media/fspl/fspl/entity"
|
|||
|
||||
func (this *generator) generateTypeIndex () (*llvm.TypeInt, error) {
|
||||
ty, err := this.typedef(entity.Key {
|
||||
Name: "Index",
|
||||
Type: "Index",
|
||||
})
|
||||
if err != nil { return nil, err }
|
||||
return ty.(*llvm.TypeInt), nil
|
||||
|
@ -17,7 +17,7 @@ func (this *generator) generateTypeIndex () (*llvm.TypeInt, error) {
|
|||
func (this *generator) generateTypeNamed (ty *entity.TypeNamed) (llvm.Type, error) {
|
||||
underlying, err := this.typedef(entity.Key {
|
||||
Unit: ty.Type.Unit(),
|
||||
Name: ty.Name,
|
||||
Type: ty.Name,
|
||||
})
|
||||
if err != nil { return nil, err }
|
||||
return &llvm.TypeDefined { Source: underlying }, nil
|
||||
|
|
Loading…
Reference in New Issue