Skip to content

Commit

Permalink
Merge #20
Browse files Browse the repository at this point in the history
Converted `gen` package to use an internal CFG based representation
  • Loading branch information
RealA10N authored Dec 30, 2024
2 parents d08dc5f + e88da74 commit b15b138
Show file tree
Hide file tree
Showing 70 changed files with 1,999 additions and 1,442 deletions.
3 changes: 3 additions & 0 deletions examples/empty.usm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
func @main {

}
4 changes: 4 additions & 0 deletions examples/loop.usm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
func @main {
.loop
j .loop
}
9 changes: 9 additions & 0 deletions examples/terminate.usm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
func @main {
%n = $64 #0
.loop
put %n
%n = add %n $64 #1
%cond = add %n $64 #-10
jnz %cond .loop
term
}
58 changes: 0 additions & 58 deletions gen/argument.go

This file was deleted.

44 changes: 44 additions & 0 deletions gen/argument_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package gen

import (
"alon.kr/x/list"
"alon.kr/x/usm/core"
"alon.kr/x/usm/parse"
)

type ArgumentGenerator struct {
RegisterArgumentGenerator InstructionContextGenerator[parse.RegisterNode, ArgumentInfo]
ImmediateArgumentGenerator InstructionContextGenerator[parse.ImmediateNode, ArgumentInfo]
LabelArgumentGenerator InstructionContextGenerator[parse.LabelNode, ArgumentInfo]
}

func NewArgumentGenerator() InstructionContextGenerator[parse.ArgumentNode, ArgumentInfo] {
return InstructionContextGenerator[parse.ArgumentNode, ArgumentInfo](
&ArgumentGenerator{
RegisterArgumentGenerator: NewRegisterArgumentGenerator(),
ImmediateArgumentGenerator: NewImmediateArgumentGenerator(),
LabelArgumentGenerator: NewLabelArgumentGenerator(),
},
)
}

func (g *ArgumentGenerator) Generate(
ctx *InstructionGenerationContext,
node parse.ArgumentNode,
) (ArgumentInfo, core.ResultList) {
switch typedNode := node.(type) {
case parse.RegisterNode:
return g.RegisterArgumentGenerator.Generate(ctx, typedNode)
case parse.ImmediateNode:
return g.ImmediateArgumentGenerator.Generate(ctx, typedNode)
case parse.LabelNode:
return g.LabelArgumentGenerator.Generate(ctx, typedNode)
default:
v := node.View()
return nil, list.FromSingle(core.Result{{
Type: core.InternalErrorResult,
Message: "Unsupported argument type",
Location: &v,
}})
}
}
21 changes: 12 additions & 9 deletions gen/argument_test.go → gen/argument_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ func TestUndefinedRegisterArgument(t *testing.T) {
unmanaged := src.Unmanaged()
node := parse.RegisterNode{TokenNode: parse.TokenNode{UnmanagedSourceView: unmanaged}}

ctx := gen.FunctionGenerationContext[Instruction]{
FileGenerationContext: &gen.FileGenerationContext[Instruction]{
GenerationContext: &gen.GenerationContext[Instruction]{
Instructions: &InstructionMap{},
PointerSize: 8,
ctx := gen.InstructionGenerationContext{
FunctionGenerationContext: &gen.FunctionGenerationContext{
FileGenerationContext: &gen.FileGenerationContext{
GenerationContext: &gen.GenerationContext{
Instructions: &InstructionMap{},
PointerSize: 8,
},
SourceContext: src.Ctx(),
Types: &TypeMap{},
},
SourceContext: src.Ctx(),
Types: &TypeMap{},
Registers: &RegisterMap{},
},
Registers: &RegisterMap{},
InstructionInfo: gen.NewEmptyInstructionInfo(&unmanaged),
}

generator := gen.NewArgumentGenerator[Instruction]()
generator := gen.NewArgumentGenerator()
_, results := generator.Generate(&ctx, node)

assert.EqualValues(t, 1, results.Len())
Expand Down
13 changes: 13 additions & 0 deletions gen/argument_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package gen

import "alon.kr/x/usm/core"

type ArgumentInfo interface {
// A pointer to the ReferencedTypeInfo instance that corresponds to the
// type of the argument. Nil if the argument does not have a type (for
// example, a label).
GetType() *ReferencedTypeInfo

// The location where the argument appears in the source code.
Declaration() core.UnmanagedSourceView
}
31 changes: 31 additions & 0 deletions gen/basic_block_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package gen

type BasicBlockInfo struct {
Instructions []*InstructionInfo

ForwardEdges []*BasicBlockInfo
BackwardEdges []*BasicBlockInfo

// All basic blocks in a function have a defined ordering between them.
// The initial ordering that the USM engine produces is the order in which
// the basic blocks appear in the source code.
// the `NextBlock` field points to the next block that follows this block
// in the ordering, or nil if this is the last basic block in the function.
NextBlock *BasicBlockInfo
}

func NewEmptyBasicBlockInfo() *BasicBlockInfo {
return &BasicBlockInfo{
Instructions: []*InstructionInfo{},

ForwardEdges: []*BasicBlockInfo{},
BackwardEdges: []*BasicBlockInfo{},

NextBlock: nil,
}
}

func (b *BasicBlockInfo) AppendInstruction(instruction *InstructionInfo) {
b.Instructions = append(b.Instructions, instruction)
instruction.LinkToBasicBlock(b)
}
46 changes: 21 additions & 25 deletions gen/file.go → gen/file_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,31 @@ import (
"alon.kr/x/usm/parse"
)

type FileInfo[InstT BaseInstruction] struct {
Functions []*FunctionInfo[InstT]
type FileGenerator struct {
NamedTypeGenerator FileContextGenerator[parse.TypeDeclarationNode, *NamedTypeInfo]
FunctionGenerator FileContextGenerator[parse.FunctionNode, *FunctionInfo]
}

type FileGenerator[InstT BaseInstruction] struct {
NamedTypeGenerator FileContextGenerator[InstT, parse.TypeDeclarationNode, *NamedTypeInfo]
FunctionGenerator FileContextGenerator[InstT, parse.FunctionNode, *FunctionInfo[InstT]]
}

func NewFileGenerator[InstT BaseInstruction]() FileGenerator[InstT] {
return FileGenerator[InstT]{
NamedTypeGenerator: NewNamedTypeGenerator[InstT](),
FunctionGenerator: NewFunctionGenerator[InstT](),
func NewFileGenerator() FileGenerator {
return FileGenerator{
NamedTypeGenerator: NewNamedTypeGenerator(),
FunctionGenerator: NewFunctionGenerator(),
}
}

func (g *FileGenerator[InstT]) createFileContext(
ctx *GenerationContext[InstT],
func (g *FileGenerator) createFileContext(
ctx *GenerationContext,
source core.SourceContext,
) *FileGenerationContext[InstT] {
return &FileGenerationContext[InstT]{
) *FileGenerationContext {
return &FileGenerationContext{
GenerationContext: ctx,
SourceContext: source,
Types: ctx.TypeManagerCreator(),
}
}

func (g *FileGenerator[InstT]) generateTypesFromDeclarations(
ctx *FileGenerationContext[InstT],
func (g *FileGenerator) generateTypesFromDeclarations(
ctx *FileGenerationContext,
nodes []parse.TypeDeclarationNode,
) (types []*NamedTypeInfo, results core.ResultList) {
types = make([]*NamedTypeInfo, len(nodes))
Expand All @@ -45,11 +41,11 @@ func (g *FileGenerator[InstT]) generateTypesFromDeclarations(
return types, results
}

func (g *FileGenerator[InstT]) generateFunctions(
ctx *FileGenerationContext[InstT],
func (g *FileGenerator) generateFunctions(
ctx *FileGenerationContext,
nodes []parse.FunctionNode,
) (functions []*FunctionInfo[InstT], results core.ResultList) {
functions = make([]*FunctionInfo[InstT], len(nodes))
) (functions []*FunctionInfo, results core.ResultList) {
functions = make([]*FunctionInfo, len(nodes))
for i, node := range nodes {
functionInfo, curResults := g.FunctionGenerator.Generate(ctx, node)
functions[i] = functionInfo
Expand All @@ -58,11 +54,11 @@ func (g *FileGenerator[InstT]) generateFunctions(
return functions, results
}

func (g *FileGenerator[InstT]) Generate(
ctx *GenerationContext[InstT],
func (g *FileGenerator) Generate(
ctx *GenerationContext,
source core.SourceContext,
node parse.FileNode,
) (*FileInfo[InstT], core.ResultList) {
) (*FileInfo, core.ResultList) {
var results core.ResultList
fileCtx := g.createFileContext(ctx, source)

Expand All @@ -76,7 +72,7 @@ func (g *FileGenerator[InstT]) Generate(
return nil, results
}

file := &FileInfo[InstT]{
file := &FileInfo{
Functions: functions,
}

Expand Down
5 changes: 5 additions & 0 deletions gen/file_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package gen

type FileInfo struct {
Functions []*FunctionInfo
}
Loading

0 comments on commit b15b138

Please sign in to comment.