umx_asm

UMX virtual machine assembly compiler
git clone git://bsandro.tech/umx_asm
Log | Files | Refs | README | LICENSE

main.go (1521B)


      1 package main
      2 
      3 import (
      4 	"bufio"
      5 	"encoding/binary"
      6 	"fmt"
      7 	"log"
      8 	"os"
      9 	"path/filepath"
     10 	"strings"
     11 	"umx_asm/asm"
     12 )
     13 
     14 const commentSym = ";"
     15 const allowedExt = ".ums"
     16 const compileExt = ".um"
     17 
     18 func main() {
     19 	if len(os.Args) < 2 {
     20 		log.Fatal("no assembly file supplied")
     21 	}
     22 	isDebug := os.Getenv("DEBUG") == "1"
     23 	filename := os.Args[1]
     24 	if filepath.Ext(filename) != allowedExt {
     25 		log.Fatal(fmt.Sprintf("only files with %s extension are supported", allowedExt))
     26 	}
     27 	file, err := os.Open(filename)
     28 	if err != nil {
     29 		log.Fatal(err)
     30 	}
     31 	defer file.Close()
     32 
     33 	scanner := bufio.NewScanner(file)
     34 	var bytecode []byte
     35 	for scanner.Scan() {
     36 		str, _, _ := strings.Cut(scanner.Text(), commentSym)
     37 		str = strings.TrimSpace(str)
     38 		if len(str) > 0 {
     39 			ins := asm.NewInstruction(str)
     40 			buf := make([]byte, 4)
     41 			binary.BigEndian.PutUint32(buf, ins.Pack())
     42 			bytecode = append(bytecode, buf...)
     43 
     44 			if isDebug {
     45 				fmt.Println(ins.String())
     46 				fmt.Printf("%.32b\n", ins.Pack())
     47 			}
     48 		}
     49 	}
     50 	if err := scanner.Err(); err != nil {
     51 		log.Fatal(err)
     52 	}
     53 	fmt.Printf("compiled size: %d bytes\n", len(bytecode))
     54 	if isDebug {
     55 		printDebugBytecode(&bytecode)
     56 	}
     57 	// dump into file
     58 	newfilename := strings.TrimSuffix(filename, allowedExt) + compileExt
     59 	if err := os.WriteFile(newfilename, bytecode, 0660); err != nil {
     60 		log.Fatal(err)
     61 	}
     62 	fmt.Printf("%s -> %s\n", filename, newfilename)
     63 }
     64 
     65 func printDebugBytecode(bytecode *[]byte) {
     66 	for i, b := range *bytecode {
     67 		fmt.Printf("%.8b", b)
     68 		if (i+1)%4 == 0 {
     69 			fmt.Printf("\n")
     70 		}
     71 	}
     72 }