Skip to content

Commit

Permalink
Fixed a bug that resulted in a stopped VM
Browse files Browse the repository at this point in the history
  • Loading branch information
aleferri committed Nov 2, 2023
1 parent 348a833 commit 4762116
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 50 deletions.
6 changes: 2 additions & 4 deletions cmd/casmeleon/AssemblyParser.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func ParseDirective(lang casm.Language, stream parser.Stream, table *SymbolTable
if err != nil {
return casm.WrapMatchError(err, ".alias", "\n")
}
return errors.New("Unsupported yet, casmeleon v1 did not support it, anyway")
return errors.New("unsupported yet, casmeleon v1 did not support it, anyway")
}
case ".db":
{
Expand Down Expand Up @@ -144,7 +144,7 @@ func ParseDirective(lang casm.Language, stream parser.Stream, table *SymbolTable
parser.Consume(stream, text.WHITESPACE)

if stream.Peek().ID() != text.EOL {
return fmt.Errorf("Expected End Of Line after the directive '%s', found instead '%s'", directive.Value(), stream.Next().Value())
return fmt.Errorf("expected End Of Line after the directive '%s', found instead '%s'", directive.Value(), stream.Next().Value())
}
stream.Next()
return nil
Expand Down Expand Up @@ -231,12 +231,10 @@ func ParseSourceLine(lang casm.Language, stream parser.Stream, table *SymbolTabl
} else {
lastToken := stream.Next()

rawArgs := []text.Symbol{}
tokensFormat := []text.Symbol{}

for lastToken.ID() != text.EOL {
tokensFormat = append(tokensFormat, lastToken)
rawArgs = append(rawArgs, lastToken)
lastToken = stream.Next()
if lastToken.ID() == text.OperatorMinus {
lastToken = stream.Next()
Expand Down
4 changes: 2 additions & 2 deletions cmd/casmeleon/AssemblyParser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/aleferri/casmeleon/internal/casm"
"github.com/aleferri/casmeleon/pkg/asm"
"github.com/aleferri/casmeleon/pkg/text"
"github.com/aleferri/casmvm/pkg/vm"
"github.com/aleferri/casmvm/pkg/vmex"
"github.com/aleferri/casmvm/pkg/vmio"
)

Expand Down Expand Up @@ -85,7 +85,7 @@ func TestCasmProcessing(t *testing.T) {
}

log := vmio.MakeVMLoggerConsole(vmio.ALL)
ex := vm.MakeNaiveVM(lang.Executables(), log, vm.MakeVMFrame())
ex := vmex.MakeNaiveVM(lang.Executables(), log, vmex.MakeVMFrame())

ctx := asm.MakeSourceContext()
_, compilingErr := asm.AssembleSource(ex, asmProgram.list, ctx)
Expand Down
51 changes: 42 additions & 9 deletions cmd/casmeleon/Main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/aleferri/casmeleon/internal/casm"
"github.com/aleferri/casmeleon/internal/ui"
"github.com/aleferri/casmeleon/pkg/asm"
"github.com/aleferri/casmeleon/pkg/parser"
"github.com/aleferri/casmeleon/pkg/text"
"github.com/aleferri/casmvm/pkg/vm"
"github.com/aleferri/casmvm/pkg/vmex"
"github.com/aleferri/casmvm/pkg/vmio"
)

Expand All @@ -37,11 +38,39 @@ func dumpOutput(originalFileName string, ui ui.UI, output []uint8) {
}
}

func exportOutput(originalFileName string, ui ui.UI, output []uint8) {
lastDot := strings.LastIndex(originalFileName, ".")
fileNoExtension := originalFileName[0:lastDot]
out, err := os.Create(fileNoExtension + ".export.txt")
if err != nil {
ui.ReportError("Output to file failed: "+err.Error(), true)
return
}

writer := bufio.NewWriter(out)

if len(output) > 1 {
for _, v := range output[0 : len(output)-2] {
bin := strconv.FormatUint(uint64(v), 2)
writer.WriteString("8'b" + bin)
writer.WriteRune('\n')
}
}

if len(output) > 0 {
bin := strconv.FormatUint(uint64(output[len(output)-1]), 2)
writer.WriteString("8'b" + bin)
writer.WriteRune('\n')
}

writer.Flush()
}

func ParseIncludedASMFile(lang casm.Language, program *AssemblyProgram, symTable *SymbolTable, sourceFile string) error {
var programfile, programErr = os.Open(sourceFile)
if programErr != nil {
wnd, _ := os.Getwd()
return fmt.Errorf("Error during opening of file %s from %s\n", sourceFile, wnd)
return fmt.Errorf("error during opening of file %s from %s", sourceFile, wnd)
}

code := text.BuildSource(sourceFile)
Expand Down Expand Up @@ -72,7 +101,7 @@ func ParseIncludedASMFile(lang casm.Language, program *AssemblyProgram, symTable
} else {
parseErr.PrettyPrint(&code)
}
return errors.New("Error during compilation")
return errors.New("error during compilation")
}
parser.ConsumeAll(stream, text.EOL)
}
Expand All @@ -84,7 +113,7 @@ func ParseASMFile(lang casm.Language, sourceFile string) (*AssemblyProgram, erro
var programfile, programErr = os.Open(sourceFile)
if programErr != nil {
wnd, _ := os.Getwd()
return nil, fmt.Errorf("Error during opening of file %s from %s\n", sourceFile, wnd)
return nil, fmt.Errorf("error during opening of file %s from %s", sourceFile, wnd)
}

code := text.BuildSource(sourceFile)
Expand Down Expand Up @@ -117,7 +146,7 @@ func ParseASMFile(lang casm.Language, sourceFile string) (*AssemblyProgram, erro
} else {
parseErr.PrettyPrint(&code)
}
return nil, errors.New("Error during compilation")
return nil, errors.New("error during compilation")
}

parser.ConsumeAll(stream, text.EOL)
Expand All @@ -127,7 +156,7 @@ func ParseASMFile(lang casm.Language, sourceFile string) (*AssemblyProgram, erro
for _, miss := range symTable.watchList {
fmt.Printf("Missing symbol %s\n", miss.Value())
}
return nil, fmt.Errorf("Missing %d symbols:\n", len(symTable.watchList))
return nil, fmt.Errorf("missing %d symbols", len(symTable.watchList))
}
programfile.Close()
return &program, nil
Expand All @@ -139,7 +168,7 @@ func main() {
var debugMode bool
flag.BoolVar(&debugMode, "debug", false, "-debug=true|false")
var exportAssembly string
flag.StringVar(&exportAssembly, "export", "bin", "-export=bin|hex")
flag.StringVar(&exportAssembly, "export", "none", "-export=bin|hex")
flag.Parse()

tUI := ui.NewConsole(false, false)
Expand Down Expand Up @@ -194,12 +223,12 @@ func main() {
}

if errAsm != nil {
fmt.Println(errAsm.Error())
fmt.Println("Error: " + errAsm.Error())
break
}

log := vmio.MakeVMLoggerConsole(vmio.ALL)
ex := vm.MakeNaiveVM(lang.Executables(), log, vm.MakeVMFrame())
ex := vmex.MakeNaiveVM(lang.Executables(), log, vmex.MakeVMFrame())
ctx := asm.MakeSourceContext()
binaryImage, compilingErr := asm.AssembleSource(ex, program.list, ctx)

Expand All @@ -209,6 +238,10 @@ func main() {
}

dumpOutput(f, tUI, binaryImage)

if exportAssembly == "bin" {
exportOutput(f, tUI, binaryImage)
}
}
}
}
16 changes: 9 additions & 7 deletions cmd/casmeleon/OpcodeInstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/aleferri/casmeleon/internal/casm"
"github.com/aleferri/casmeleon/pkg/asm"
"github.com/aleferri/casmvm/pkg/opcodes"
"github.com/aleferri/casmvm/pkg/vmex"
)

type OpcodeInstance struct {
Expand All @@ -25,26 +26,27 @@ func MakeOpcodeInstance(opcode casm.Opcode, format ArgumentFormat, symTable *Sym

func (c *OpcodeInstance) Assemble(m opcodes.VM, addr uint32, index int, ctx asm.Context) (uint32, []uint8, error) {
k := uint16(0)
params := []uint16{}

frame := vmex.MakeVMFrame()

for _, a := range c.parameters {
m.Frame().Values().Put(k, a.Value())
frame.Values().Put(k, a.Value())
k++
if a.IsDynamic() {
//Mark dynamic symbols only
ctx.GuardSymbol(a.Name(), index, addr, c)
}
params = append(params, k)
k++
}

m.Frame().Values().Put(k, int64(addr))
frame.Values().Put(k, int64(addr))

_, err := m.Enter(c.index, params...)
err := m.Invoke(c.index, &frame)

if err != nil {
return addr, nil, err
}

outs := m.Frame().Returns()
outs := frame.Returns()
bin := []uint8{}
size := uint16(outs.Size())
for i := uint16(0); i < size; i++ {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/aleferri/casmeleon

go 1.14

require github.com/aleferri/casmvm v0.2.3
require github.com/aleferri/casmvm v0.2.6
8 changes: 4 additions & 4 deletions internal/casm/Expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

const USE_THIS_ADDR = 1

//WalkCSTExpression walk the concrete syntax tree of an expression to convert it into SSA form
// WalkCSTExpression walk the concrete syntax tree of an expression to convert it into SSA form
func WalkCSTExpression(lang *Language, params []string, types []uint32, node parser.CSTNode) (expr.Converter, error) {
listing := []opcodes.Opcode{}
status := expr.MakeConverter(node.Symbols(), uint16(len(params)))
Expand All @@ -33,7 +33,7 @@ var Precedence = map[string]int{
"!": 4, "~": 4, ".len": 4,
}

//CompileTerm compile a <Term> of the expression: either <Identifier> | <Integer> | <UnaryOp> | <ParensExpr> | <InlineCall>
// CompileTerm compile a <Term> of the expression: either <Identifier> | <Integer> | <UnaryOp> | <ParensExpr> | <InlineCall>
func CompileTerm(lang *Language, params []string, listing *[]opcodes.Opcode, status *expr.Converter) error {
if status.IsEmptyQueue() {
return nil
Expand Down Expand Up @@ -149,7 +149,7 @@ func CompileTerm(lang *Language, params []string, listing *[]opcodes.Opcode, sta
}

retLabel := status.LabelLocal()
call := opcodes.MakeEnter(retLabel, addr, refs)
call := opcodes.MakeEnter([]uint16{retLabel}, addr, refs)

*listing = append(*listing, call)
status.Push(expr.MakeLocal("ret", 0, retLabel))
Expand All @@ -170,7 +170,7 @@ func ReduceBinaryExpression(op string, listing *[]opcodes.Opcode, status *expr.C
return res
}

//CompileFactor compile the left associativity part of the expression
// CompileFactor compile the left associativity part of the expression
func CompileFactor(lang *Language, params []string, listing *[]opcodes.Opcode, status *expr.Converter) error {
if status.IsEmptyQueue() {
return nil
Expand Down
22 changes: 11 additions & 11 deletions internal/casm/Language.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (
"github.com/aleferri/casmeleon/pkg/expr"
"github.com/aleferri/casmeleon/pkg/parser"
"github.com/aleferri/casmvm/pkg/opcodes"
"github.com/aleferri/casmvm/pkg/vm"
"github.com/aleferri/casmvm/pkg/vmex"
)

//Language definition
// Language definition
type Language struct {
numberBases []NumberBase
sets []Set
opcodes []Opcode
fnList []vm.Callable
fnList []vmex.Callable
fnNames []string
endianess bool // 0 big endian, 1 little endian
}
Expand All @@ -31,7 +31,7 @@ func (l *Language) FindAddressOf(name string) (uint32, bool) {
return 0, false
}

//SetOf return the Set of a symbol
// SetOf return the Set of a symbol
func (l *Language) SetOf(s string) (*Set, bool) {
lenSets := len(l.sets) - 1
for i := range l.sets {
Expand All @@ -43,7 +43,7 @@ func (l *Language) SetOf(s string) (*Set, bool) {
return nil, false
}

//SetByName return the set by his name
// SetByName return the set by his name
func (l *Language) SetByName(s string) (*Set, bool) {
for _, set := range l.sets {
if set.name == s {
Expand Down Expand Up @@ -92,14 +92,14 @@ func (lang *Language) ParseInt(value string) (int64, error) {
return int64(v), e
}

func (lang *Language) AssignFrame(c vm.Callable, name string) int32 {
func (lang *Language) AssignFrame(c vmex.Callable, name string) int32 {
n := len(lang.fnList)
lang.fnList = append(lang.fnList, c)
lang.fnNames = append(lang.fnNames, name)
return int32(n)
}

func (lang *Language) Executables() []vm.Callable {
func (lang *Language) Executables() []vmex.Callable {
return lang.fnList
}

Expand All @@ -113,7 +113,7 @@ func MakeLanguage(root parser.CSTNode) (Language, error) {
v, _ := strconv.ParseInt(a, 10, 32)
return int32(v)
}}
lang := Language{[]NumberBase{}, []Set{labels, integers}, []Opcode{}, []vm.Callable{}, []string{}, true}
lang := Language{[]NumberBase{}, []Set{labels, integers}, []Opcode{}, []vmex.Callable{}, []string{}, true}
for _, k := range root.Children() {
switch k.ID() {
case NUMBER_BASE:
Expand Down Expand Up @@ -141,7 +141,7 @@ func MakeLanguage(root parser.CSTNode) (Language, error) {
return lang, errBody
}

callable := vm.MakeCallable(*list)
callable := vmex.MakeCallable(inline.name, inline.params, *list)

lang.fnList = append(lang.fnList, callable)
lang.fnNames = append(lang.fnNames, inline.name)
Expand All @@ -158,7 +158,7 @@ func MakeLanguage(root parser.CSTNode) (Language, error) {
fmt.Printf("Arguments were: %v\n", opcode.params)
return lang, errors.New("In Opcode " + opcode.name + ":\n" + errBody.Error())
}
lang.fnList[opcode.frame] = vm.MakeCallable(*list)
lang.fnList[opcode.frame] = vmex.MakeCallable(opcode.name, opcode.params, *list)
lang.opcodes[len(lang.opcodes)-1].runList = *list
lang.opcodes[len(lang.opcodes)-1].useAddr = useAddr
}
Expand Down Expand Up @@ -279,7 +279,7 @@ func CompileListing(lang *Language, params []string, root parser.CSTNode, listin
return listing, useAddr, nil
}

//CST Tags
// CST Tags
const (
EXPRESSION = 0
NUMBER_BASE = 1
Expand Down
10 changes: 5 additions & 5 deletions internal/casm/Opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"github.com/aleferri/casmeleon/pkg/parser"
"github.com/aleferri/casmeleon/pkg/text"
"github.com/aleferri/casmvm/pkg/opcodes"
"github.com/aleferri/casmvm/pkg/vm"
"github.com/aleferri/casmvm/pkg/vmex"
)

//Opcode declared in the assembly language
// Opcode declared in the assembly language
type Opcode struct {
name string //opcode name
params []string //opcode parameters name
Expand Down Expand Up @@ -100,13 +100,13 @@ func StringifyFormat(lang *Language, format []uint32, types []uint32) []string {
return desc
}

//Param Types
// Param Types
const (
NUMBER = 0
LABEL = 1
)

//PruneToOpcode remove the header from the opcode CST and return Opcode and Body CST
// PruneToOpcode remove the header from the opcode CST and return Opcode and Body CST
func PruneToOpcode(lang *Language, op parser.CSTNode) (Opcode, parser.CSTNode, error) {
toks := op.Symbols()
name := toks[1]
Expand Down Expand Up @@ -141,7 +141,7 @@ func PruneToOpcode(lang *Language, op parser.CSTNode) (Opcode, parser.CSTNode, e

body := children[2]
opcodeName := name.Value()
frame := lang.AssignFrame(vm.MakeCallable([]opcodes.Opcode{}), opcodeName)
frame := lang.AssignFrame(vmex.MakeCallable("", []string{}, []opcodes.Opcode{}), opcodeName)
return Opcode{name: opcodeName, format: argsFormat, params: params, types: types, frame: frame}, body, nil
}

Expand Down
Loading

0 comments on commit 4762116

Please sign in to comment.