rename
This commit is contained in:
parent
c56b6c92db
commit
8a6a4127b5
1 changed files with 0 additions and 0 deletions
|
|
@ -1,977 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var register_map = map[string]int{
|
||||
"A": 0,
|
||||
"X": 1,
|
||||
"L": 2,
|
||||
"B": 3,
|
||||
"S": 4,
|
||||
"T": 5,
|
||||
"F": 6,
|
||||
}
|
||||
|
||||
var ukazna_tabela = map[string]int{
|
||||
"ADD": 0x18,
|
||||
"ADDF": 0x58,
|
||||
"ADDR": 0x90,
|
||||
"AND": 0x40,
|
||||
"CLEAR": 0xB4,
|
||||
"COMP": 0x28,
|
||||
"COMPF": 0x88,
|
||||
"COMPR": 0xA0,
|
||||
"DIV": 0x24,
|
||||
"DIVF": 0x64,
|
||||
"DIVR": 0x9C,
|
||||
"FIX": 0xC4,
|
||||
"FLOAT": 0xC0,
|
||||
"HIO": 0xF4,
|
||||
"J": 0x3C,
|
||||
"JEQ": 0x30,
|
||||
"JGT": 0x34,
|
||||
"JLT": 0x38,
|
||||
"JSUB": 0x48,
|
||||
"LDA": 0x00,
|
||||
"LDB": 0x68,
|
||||
"LDCH": 0x50,
|
||||
"LDF": 0x70,
|
||||
"LDL": 0x08,
|
||||
"LDS": 0x6C,
|
||||
"LDT": 0x74,
|
||||
"LDX": 0x04,
|
||||
"LPS": 0xD0,
|
||||
"MUL": 0x20,
|
||||
"MULF": 0x60,
|
||||
"MULR": 0x98,
|
||||
"NORM": 0xC8,
|
||||
"OR": 0x44,
|
||||
"RD": 0xD4,
|
||||
"RMO": 0xAC,
|
||||
"RSUB": 0x4C,
|
||||
"SHIFTL": 0xA4,
|
||||
"SHIFTR": 0xA8,
|
||||
"SIO": 0xF0,
|
||||
"SSK": 0xEC,
|
||||
"STA": 0x0C,
|
||||
"STB": 0x78,
|
||||
"STCH": 0x54,
|
||||
"STF": 0x80,
|
||||
"STI": 0xD4,
|
||||
"STL": 0x14,
|
||||
"STS": 0x74,
|
||||
"STSW": 0xE8,
|
||||
"STT": 0x84,
|
||||
"STX": 0x10,
|
||||
"SUB": 0x1C,
|
||||
"SUBF": 0x5C,
|
||||
"SUBR": 0x94,
|
||||
"SVC": 0xB0,
|
||||
"TD": 0xE0,
|
||||
"TIO": 0xF8,
|
||||
"TIX": 0x2C,
|
||||
"TIXR": 0xB8,
|
||||
"WD": 0xDC,
|
||||
}
|
||||
|
||||
var simbolna_tabela = map[string]int{}
|
||||
|
||||
var ime_programa string
|
||||
|
||||
var lc_global int
|
||||
|
||||
var bazno_dovoljeno bool
|
||||
|
||||
var bazno_naslov int
|
||||
|
||||
var naslov_programa int
|
||||
|
||||
var zacetni_naslov int
|
||||
|
||||
type M_zapis struct {
|
||||
odmik int
|
||||
dolzina int
|
||||
}
|
||||
|
||||
var M_tabela []M_zapis
|
||||
|
||||
type ukaz interface {
|
||||
Velikost() int
|
||||
GetAddr() int
|
||||
}
|
||||
|
||||
func (f *format_F1) Velikost() int { return f.velikost }
|
||||
func (f *format_F2_n) Velikost() int { return f.velikost }
|
||||
func (f *format_F2_r) Velikost() int { return f.velikost }
|
||||
func (f *format_F2_rn) Velikost() int { return f.velikost }
|
||||
func (f *format_F2_rr) Velikost() int { return f.velikost }
|
||||
func (f *format_F3_m) Velikost() int { return f.velikost }
|
||||
func (f *format_F4_m) Velikost() int { return f.velikost }
|
||||
func (f *format_D) Velikost() int { return f.velikost }
|
||||
func (f *format_D_n) Velikost() int { return f.velikost }
|
||||
func (f *format_M_i) Velikost() int { return f.velikost }
|
||||
func (f *format_M_r) Velikost() int { return f.velikost }
|
||||
|
||||
func (f *format_F1) GetAddr() int { return f.lc }
|
||||
func (f *format_F2_n) GetAddr() int { return f.lc }
|
||||
func (f *format_F2_r) GetAddr() int { return f.lc }
|
||||
func (f *format_F2_rn) GetAddr() int { return f.lc }
|
||||
func (f *format_F2_rr) GetAddr() int { return f.lc }
|
||||
func (f *format_F3_m) GetAddr() int { return f.lc }
|
||||
func (f *format_F4_m) GetAddr() int { return f.lc }
|
||||
func (f *format_D) GetAddr() int { return f.lc }
|
||||
func (f *format_D_n) GetAddr() int { return f.lc }
|
||||
func (f *format_M_i) GetAddr() int { return f.lc }
|
||||
func (f *format_M_r) GetAddr() int { return f.lc }
|
||||
|
||||
var register string = `A|X|L|B|S|T|F`
|
||||
|
||||
type format_F1 struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // F1 - 1, F2 - 2, F3 - 3, F4 - 4, SIC - 5
|
||||
velikost int //v bajtih
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F2_n struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 2
|
||||
velikost int
|
||||
n string
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F2_r struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 6
|
||||
velikost int
|
||||
r1 string
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F2_rn struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 2
|
||||
velikost int
|
||||
r1 string
|
||||
n string
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F2_rr struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 2
|
||||
velikost int
|
||||
r1 string
|
||||
r2 string
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F3_m struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 3
|
||||
velikost int
|
||||
naslov string
|
||||
odmik int
|
||||
x bool
|
||||
b bool
|
||||
p bool
|
||||
e bool
|
||||
n bool
|
||||
i bool
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_F4_m struct {
|
||||
oznaka string
|
||||
opcode int
|
||||
format int // 4
|
||||
velikost int
|
||||
naslov string
|
||||
odmik int
|
||||
x bool
|
||||
b bool
|
||||
p bool
|
||||
e bool
|
||||
n bool
|
||||
i bool
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_D struct {
|
||||
oznaka string
|
||||
ime string //NOBASE
|
||||
format int // 6
|
||||
velikost int
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_D_n struct {
|
||||
oznaka string
|
||||
ime string
|
||||
format int // 7
|
||||
velikost int
|
||||
operand string
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_M_r struct {
|
||||
oznaka string
|
||||
ime string
|
||||
format int // 8
|
||||
velikost int
|
||||
operand string
|
||||
rezervacija int
|
||||
lc int
|
||||
}
|
||||
|
||||
type format_M_i struct {
|
||||
oznaka string
|
||||
ime string
|
||||
format int // 9
|
||||
velikost int
|
||||
operand string
|
||||
lc int
|
||||
}
|
||||
|
||||
func remove_comments_and_empty_lines(el string) bool {
|
||||
match_pure_comment, err := regexp.MatchString(`(?m)^[\t ]*\..*$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_pure_comment {
|
||||
return true
|
||||
}
|
||||
match_empty, err := regexp.MatchString(`(?m)^[\t ]*$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_empty {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F1(el string, AST *[]ukaz) bool {
|
||||
match_F1, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F1 {
|
||||
var nov_ukaz format_F1
|
||||
nov_ukaz.format = 1
|
||||
nov_ukaz.velikost = 1
|
||||
pattern := regexp.MustCompile(`[\t ]+[A-Za-z]+`)
|
||||
mnemonik := strings.Trim(pattern.FindString(el), "\t ")
|
||||
val, ok := ukazna_tabela[mnemonik];
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
//fmt.Println("F1: ", mnemonik, nov_ukaz.opcode)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F2_n(el string, AST *[]ukaz) bool {
|
||||
match_F2_n, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+SVC ([0-9]+)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F2_n {
|
||||
var nov_ukaz format_F2_n
|
||||
nov_ukaz.format = 2
|
||||
nov_ukaz.velikost = 2
|
||||
nov_ukaz.opcode = 10
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_par := regexp.MustCompile(`[\t ]+[0-9]+,?`)
|
||||
temp := strings.Trim(re_par.FindString(el), "\t ")
|
||||
if temp[len(temp) - 1] == ',' {
|
||||
nov_ukaz.n = strings.TrimRight(temp, ",")
|
||||
} else {
|
||||
nov_ukaz.n = temp
|
||||
}
|
||||
//fmt.Println("F2_n ", el[:len(el) - 1], nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F2_r(el string, AST *[]ukaz) bool {
|
||||
match_F2_r, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ (`+register+`)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F2_r {
|
||||
var nov_ukaz format_F2_r
|
||||
nov_ukaz.format = 2
|
||||
nov_ukaz.velikost = 2
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`)
|
||||
val, ok := ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")]
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
re_par := regexp.MustCompile(`[\t ]+[A-Za-z]+ (`+register+`)`)
|
||||
nov_ukaz.r1 = strings.Split(strings.Trim(re_par.FindString(el), "\t \n"), " ")[1]
|
||||
//fmt.Println(nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F2_rn(el string, AST *[]ukaz) bool {
|
||||
match_F2_rn, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ (`+register+`), ([0-9]+)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F2_rn {
|
||||
var nov_ukaz format_F2_rn
|
||||
nov_ukaz.format = 2
|
||||
nov_ukaz.velikost = 2
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`)
|
||||
val, ok := ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")]
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
re_par1 := regexp.MustCompile(`[\t ]+[A-Za-z]+ (`+register+`)`)
|
||||
nov_ukaz.r1 = strings.Split(strings.Trim(re_par1.FindString(el), "\t \n"), " ")[1]
|
||||
re_par2 := regexp.MustCompile(`(`+register+`), ([0-9]+),?`)
|
||||
temp := strings.Split(re_par2.FindString(el), " ")[1]
|
||||
if temp[len(temp) - 1] == ',' {
|
||||
nov_ukaz.n = strings.TrimRight(temp, ",")
|
||||
} else {
|
||||
nov_ukaz.n = temp
|
||||
}
|
||||
//fmt.Println("F2_rn: ", el[:len(el) - 1], nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F2_rr(el string, AST *[]ukaz) bool {
|
||||
match_F2_rr, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ (`+register+`), (`+register+`)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F2_rr {
|
||||
var nov_ukaz format_F2_rr
|
||||
nov_ukaz.format = 2
|
||||
nov_ukaz.velikost = 2
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Z-a-z_]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`)
|
||||
val, ok := ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")]
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
re_par1 := regexp.MustCompile(`[\t ]+[A-Za-z]+ (`+register+`)`)
|
||||
nov_ukaz.r1 = strings.Split(strings.Trim(re_par1.FindString(el), "\t \n"), " ")[1]
|
||||
re_par2 := regexp.MustCompile(`(`+register+`), (`+register+`)`)
|
||||
nov_ukaz.r2 = strings.Split(re_par2.FindString(el), " ")[1]
|
||||
//fmt.Println("F2_rr: ", nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F3_m(el string, AST *[]ukaz) bool {
|
||||
match_F3_m, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z]+ ((#?|@?)[A-Za-z]+|(#?|@?)[0-9+]+)(, X)?[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F3_m {
|
||||
var nov_ukaz format_F3_m
|
||||
nov_ukaz.format = 3
|
||||
nov_ukaz.velikost = 3
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_op := regexp.MustCompile(`[\t ]+[A-Za-z]+`)
|
||||
val, ok := ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")]
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
// naslov
|
||||
re_par1 := regexp.MustCompile(`[\t ]+[A-Za-z]+ ((#?|@?)[A-Za-z]+|(#?|@?)[0-9+]+)`)
|
||||
nov_ukaz.naslov = strings.Split(strings.Trim(re_par1.FindString(el), "\t \n"), " ")[1]
|
||||
if nov_ukaz.naslov[0] == '@' {
|
||||
nov_ukaz.n = true
|
||||
nov_ukaz.i = false
|
||||
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
|
||||
} else if nov_ukaz.naslov[0] == '#' {
|
||||
nov_ukaz.n = false
|
||||
nov_ukaz.i = true
|
||||
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
|
||||
} else {
|
||||
//temp
|
||||
nov_ukaz.n = true
|
||||
nov_ukaz.i = true
|
||||
}
|
||||
// indeksno naslavljanje
|
||||
re_x := regexp.MustCompile(`(, X)[\t ]*(\..*)?\n`)
|
||||
if re_x.FindString(el) != "" {
|
||||
nov_ukaz.x = true
|
||||
} else {
|
||||
nov_ukaz.x = false
|
||||
}
|
||||
nov_ukaz.e = false
|
||||
//fmt.Println(el, nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_F4_m(el string, AST *[]ukaz) bool {
|
||||
match_F4_m, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+\+[A-Za-z]+ ((#?|@?)[A-Za-z]+|(#?|@?)[0-9+]+)(, X)?[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_F4_m {
|
||||
var nov_ukaz format_F4_m
|
||||
nov_ukaz.format = 4
|
||||
nov_ukaz.velikost = 4
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nov_ukaz.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nov_ukaz.oznaka = ""
|
||||
}
|
||||
re_op := regexp.MustCompile(`[\t ]+\+[A-Za-z]+`)
|
||||
// skip "+"
|
||||
val, ok := ukazna_tabela[strings.Trim(re_op.FindString(el), "\t +")]
|
||||
if !ok {
|
||||
fmt.Println("Error: Opcode not found.")
|
||||
return false
|
||||
}
|
||||
nov_ukaz.opcode = val
|
||||
// naslov
|
||||
re_par1 := regexp.MustCompile(`[\t ]+\+[A-Za-z]+ ((#?|@?)[A-Za-z]+|(#?|@?)[0-9+]+)`)
|
||||
nov_ukaz.naslov = strings.Split(strings.Trim(re_par1.FindString(el), "\t \n"), " ")[1]
|
||||
if nov_ukaz.naslov[0] == '@' {
|
||||
nov_ukaz.n = true
|
||||
nov_ukaz.i = false
|
||||
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
|
||||
} else if nov_ukaz.naslov[0] == '#' {
|
||||
nov_ukaz.n = false
|
||||
nov_ukaz.i = true
|
||||
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
|
||||
} else {
|
||||
nov_ukaz.n = true
|
||||
nov_ukaz.i = true
|
||||
}
|
||||
// indeksno naslavljanje
|
||||
re_x := regexp.MustCompile(`(, X)[\t ]*(\..*)?\n`)
|
||||
if re_x.FindString(el) != "" {
|
||||
nov_ukaz.x = true
|
||||
} else {
|
||||
nov_ukaz.x = false
|
||||
}
|
||||
nov_ukaz.e = true
|
||||
//fmt.Println(el, nov_ukaz)
|
||||
*AST = append(*AST, &nov_ukaz)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_D(el string, AST *[]ukaz) bool {
|
||||
match_D, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+NOBASE[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_D {
|
||||
var nova_direktiva format_D
|
||||
nova_direktiva.ime = "NOBASE"
|
||||
nova_direktiva.format = 6
|
||||
nova_direktiva.velikost = 0
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nova_direktiva.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nova_direktiva.oznaka = ""
|
||||
}
|
||||
*AST = append(*AST, &nova_direktiva)
|
||||
//fmt.Println(el, nova_direktiva)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_D_n(el string, AST *[]ukaz) bool {
|
||||
match_D_n, err := regexp.MatchString(`(?m)^[A-Za-z]*[\t ]+(START|END|ORG|EQU|BASE) ([A-Za-z\+\-\*]+|[0-9\+\-\*]+)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_D_n {
|
||||
var nova_direktiva format_D_n
|
||||
re_ime := regexp.MustCompile(`START|END|ORG|EQU|BASE`)
|
||||
nova_direktiva.ime = re_ime.FindString(el)
|
||||
nova_direktiva.format = 7
|
||||
nova_direktiva.velikost = 0
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nova_direktiva.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nova_direktiva.oznaka = ""
|
||||
}
|
||||
re_ope := regexp.MustCompile(`(START|END|ORG|EQU|BASE) ([A-Za-z\+\-\*]+|[0-9\+\-\*]+)`)
|
||||
nova_direktiva.operand = strings.Split(re_ope.FindString(el), " ")[1]
|
||||
*AST = append(*AST, &nova_direktiva)
|
||||
//fmt.Println(el, nova_direktiva)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_M_r(el string, AST *[]ukaz) bool {
|
||||
match_M_r, err := regexp.MatchString(`(?m)^[A-Za-z]*[\t ]+(RESW|RESB) ([0-9]+)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_M_r {
|
||||
var nova_direktiva format_M_r
|
||||
re_ime := regexp.MustCompile(`RESW|RESB`)
|
||||
nova_direktiva.ime = re_ime.FindString(el)
|
||||
nova_direktiva.format = 8
|
||||
nova_direktiva.velikost = 0
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nova_direktiva.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nova_direktiva.oznaka = ""
|
||||
}
|
||||
re_ope := regexp.MustCompile(`[0-9]+`)
|
||||
nova_direktiva.operand = re_ope.FindString(el)
|
||||
operand_int, _ := strconv.Atoi(nova_direktiva.operand)
|
||||
if nova_direktiva.ime == "RESW" {
|
||||
nova_direktiva.rezervacija = 3 * operand_int
|
||||
} else {
|
||||
nova_direktiva.rezervacija = operand_int
|
||||
}
|
||||
//fmt.Println(el, nova_direktiva)
|
||||
*AST = append(*AST, &nova_direktiva)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func check_M_i(el string, AST *[]ukaz) bool {
|
||||
match_M_i, err := regexp.MatchString(`(?m)^[A-Za-z]*[\t ]+(WORD|BYTE) ([0-9]+)[\t ]*(\..*)?$\n`, el)
|
||||
if err != nil {
|
||||
fmt.Println("Error while matching string.")
|
||||
}
|
||||
if match_M_i {
|
||||
var nova_direktiva format_M_i
|
||||
re_ime := regexp.MustCompile(`WORD|BYTE`)
|
||||
nova_direktiva.ime = re_ime.FindString(el)
|
||||
nova_direktiva.format = 9
|
||||
if !(strings.HasPrefix(el, " ") || strings.HasPrefix(el, "\t")) {
|
||||
re := regexp.MustCompile(`(?m)^[A-Za-z]+`)
|
||||
nova_direktiva.oznaka = re.FindString(el)
|
||||
} else {
|
||||
nova_direktiva.oznaka = ""
|
||||
}
|
||||
re_ope := regexp.MustCompile(`[0-9]+`)
|
||||
nova_direktiva.operand = re_ope.FindString(el)
|
||||
if nova_direktiva.ime == "WORD" {
|
||||
nova_direktiva.velikost = 3
|
||||
} else {
|
||||
nova_direktiva.velikost = 1
|
||||
}
|
||||
//fmt.Println(el, nova_direktiva)
|
||||
*AST = append(*AST, &nova_direktiva)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func prvi_prehod(AST *[]ukaz) {
|
||||
lc_global, _ = strconv.Atoi((*AST)[0].(*format_D_n).operand)
|
||||
naslov_programa = lc_global
|
||||
ime_programa = (*AST)[0].(*format_D_n).oznaka
|
||||
for _, el := range *AST {
|
||||
//fmt.Printf("lc_global '%x'\n", lc_global)
|
||||
switch val := el.(type) {
|
||||
case *format_F1: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
case *format_F2_n: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
case *format_F2_r: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
case *format_F2_rn: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
case *format_F2_rr: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
case *format_F3_m: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
if bazno_dovoljeno {
|
||||
val.b = true
|
||||
}
|
||||
case *format_F4_m: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
if bazno_dovoljeno {
|
||||
val.b = true
|
||||
}
|
||||
case *format_D: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
bazno_dovoljeno = false
|
||||
case *format_D_n: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
switch val.ime {
|
||||
case "ORG": inc, _ := strconv.Atoi(val.operand)
|
||||
lc_global += inc
|
||||
case "BASE": bazno_dovoljeno = true
|
||||
}
|
||||
case *format_M_r: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.rezervacija
|
||||
case *format_M_i: val.lc = lc_global
|
||||
if val.oznaka != "" {
|
||||
simbolna_tabela[val.oznaka] = lc_global
|
||||
}
|
||||
lc_global += val.velikost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func drugi_prehod(AST *[]ukaz) {
|
||||
for _, el := range *AST {
|
||||
switch val := el.(type) {
|
||||
case *format_F3_m: if st, err := strconv.Atoi(val.naslov); err == nil {
|
||||
if val.n && !val.i {
|
||||
if st >= -2048 && st <= 2047 {
|
||||
val.p = true
|
||||
val.odmik = st - (val.lc + val.velikost) //naslov - PC
|
||||
} else if bazno_dovoljeno && st >= 0 && st <= 4095 {
|
||||
val.odmik = st - bazno_naslov
|
||||
val.b = true
|
||||
} else {
|
||||
val.odmik = st
|
||||
}
|
||||
} else if !val.n && val.i {
|
||||
val.odmik = st
|
||||
} else if val.n && val.i {
|
||||
if st >= -2048 && st <= 2047 {
|
||||
val.p = true
|
||||
val.odmik = st - (val.lc + val.velikost) //naslov - PC
|
||||
} else if bazno_dovoljeno && st >= 0 && st <= 4095 {
|
||||
val.b = true
|
||||
val.odmik = st - bazno_naslov
|
||||
} else {
|
||||
val.odmik = st
|
||||
}
|
||||
}
|
||||
} else {
|
||||
naslov := simbolna_tabela[val.naslov]
|
||||
if val.n && !val.i {
|
||||
if naslov >= -2048 && naslov <= 2047 {
|
||||
val.p = true
|
||||
val.odmik = naslov - (val.lc + val.velikost) //naslov - PC
|
||||
} else if bazno_dovoljeno && naslov >= 0 && naslov <= 4095 {
|
||||
val.b = true
|
||||
val.odmik = naslov - bazno_naslov
|
||||
} else {
|
||||
val.odmik = naslov
|
||||
}
|
||||
} else if !val.n && val.i {
|
||||
val.odmik = naslov
|
||||
} else if val.n && val.i {
|
||||
if naslov >= -2048 && naslov <= 2047 {
|
||||
val.p = true
|
||||
val.odmik = naslov - (val.lc + val.velikost) //naslov - PC
|
||||
//fmt.Printf("pc %x\n", val.odmik)
|
||||
} else if bazno_dovoljeno && naslov >= 0 && naslov <= 4095 {
|
||||
val.b = true
|
||||
val.odmik = naslov - bazno_naslov
|
||||
//fmt.Printf("bazno %x\n", val.odmik)
|
||||
} else {
|
||||
val.odmik = naslov
|
||||
//fmt.Printf("neposredno %x\n", val.odmik)
|
||||
}
|
||||
}
|
||||
}
|
||||
case *format_F4_m: if st, err := strconv.Atoi(val.naslov); err == nil {
|
||||
val.odmik = st
|
||||
} else {
|
||||
val.odmik = simbolna_tabela[val.naslov]
|
||||
m := M_zapis{val.lc + 1, 5}
|
||||
M_tabela = append(M_tabela, m)
|
||||
}
|
||||
case *format_D: bazno_dovoljeno = false
|
||||
case *format_D_n: switch val.ime {
|
||||
case "BASE": bazno_dovoljeno = true
|
||||
if st, err := strconv.Atoi(val.operand); err == nil {
|
||||
bazno_naslov = st
|
||||
} else {
|
||||
bazno_naslov = simbolna_tabela[val.operand]
|
||||
}
|
||||
case "END": if st, err := strconv.Atoi(val.operand); err == nil {
|
||||
zacetni_naslov = st
|
||||
} else {
|
||||
zacetni_naslov = simbolna_tabela[val.operand]
|
||||
}
|
||||
case "EQU": if st, err := strconv.Atoi(val.operand); err == nil {
|
||||
simbolna_tabela[val.oznaka] = st
|
||||
} else {
|
||||
simbolna_tabela[val.oznaka] = simbolna_tabela[val.operand]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generacija(AST *[]ukaz) {
|
||||
obj, err := os.Create("out.obj")
|
||||
if err != nil {
|
||||
fmt.Println("Error creating a file: ", err)
|
||||
return
|
||||
}
|
||||
defer obj.Close()
|
||||
obj.WriteString(fmt.Sprintf("H%-*s%06x%06x\n", 6, ime_programa, naslov_programa, lc_global + (*AST)[len(*AST) - 1].Velikost() - naslov_programa))
|
||||
line_len := 0
|
||||
line := ""
|
||||
line_addr := naslov_programa
|
||||
for _, el := range *AST {
|
||||
temp := ""
|
||||
switch val := el.(type) {
|
||||
case *format_F1: temp= fmt.Sprintf("%s%02x", temp, val.opcode)
|
||||
case *format_F2_n: temp = fmt.Sprintf("%s%02x%x%x", temp, val.opcode, val.n, 0)
|
||||
case *format_F2_r: temp = fmt.Sprintf("%s%02x%x%x", temp, val.opcode, register_map[val.r1], 0)
|
||||
case *format_F2_rn: temp = fmt.Sprintf("%s%02x%x%x", temp, val.opcode, val.r1, val.n)
|
||||
case *format_F2_rr: temp = fmt.Sprintf("%s%02x%x%x", temp, val.opcode, register_map[val.r1], register_map[val.r2])
|
||||
case *format_F3_m: n := 0
|
||||
i := 0
|
||||
x := 0
|
||||
b := 0
|
||||
p := 0
|
||||
e := 0
|
||||
if val.n {
|
||||
n = 1
|
||||
}
|
||||
if val.i {
|
||||
i = 1
|
||||
}
|
||||
if val.x {
|
||||
x = 1
|
||||
}
|
||||
if val.b {
|
||||
b = 1
|
||||
}
|
||||
if val.p {
|
||||
p = 1
|
||||
}
|
||||
if val.e {
|
||||
e = 1
|
||||
}
|
||||
temp = fmt.Sprintf("%s%02x%02x%02x", temp, val.opcode + (n << 1) + i, (x << 7) + (b << 6) + (p << 5) + (e << 4) +
|
||||
((val.odmik >> 8) & 0xF), val.odmik & 0xFF)
|
||||
case *format_F4_m: n := 0
|
||||
i := 0
|
||||
x := 0
|
||||
b := 0
|
||||
p := 0
|
||||
e := 0
|
||||
if val.n {
|
||||
n = 1
|
||||
}
|
||||
if val.i {
|
||||
i = 1
|
||||
}
|
||||
if val.x {
|
||||
x = 1
|
||||
}
|
||||
if val.b {
|
||||
b = 1
|
||||
}
|
||||
if val.p {
|
||||
p = 1
|
||||
}
|
||||
if val.e {
|
||||
e = 1
|
||||
}
|
||||
temp = fmt.Sprintf("%s%02x%02x%02x%02x", temp, val.opcode + (n << 1) + i, (x << 7) + (b << 6) + (p << 5) + (e << 4) +
|
||||
((val.odmik >> 16) & 0xF), (val.odmik >> 8) & 0xFF, val.odmik & 0xFF)
|
||||
case *format_D: continue
|
||||
case *format_D_n: if val.ime == "START" || val.ime == "END" {
|
||||
continue
|
||||
}
|
||||
case *format_M_r: continue
|
||||
case *format_M_i: vr, _ := strconv.Atoi(val.operand)
|
||||
temp = fmt.Sprintf("%s%06x", temp, vr)
|
||||
}
|
||||
if line_len + el.Velikost() <= 30 {
|
||||
line_len += el.Velikost()
|
||||
line = fmt.Sprintf("%s%s", line, temp)
|
||||
} else {
|
||||
obj.WriteString(fmt.Sprintf("T%06x%02x%s\n", line_addr, line_len, line))
|
||||
line_len = el.Velikost()
|
||||
line = temp
|
||||
line_addr = el.GetAddr()
|
||||
}
|
||||
}
|
||||
obj.WriteString(fmt.Sprintf("T%06x%02x%s\n", line_addr, line_len, line))
|
||||
for _, el := range M_tabela {
|
||||
obj.WriteString(fmt.Sprintf("M%06x%02x\n", el.odmik, el.dolzina))
|
||||
}
|
||||
obj.WriteString(fmt.Sprintf("E%06x", zacetni_naslov))
|
||||
}
|
||||
|
||||
func izpis(AST *[]ukaz) {
|
||||
for _, el := range *AST {
|
||||
switch val := el.(type) {
|
||||
case *format_F1: fmt.Println("F1", val)
|
||||
case *format_F2_n: fmt.Println("F2_n", val)
|
||||
case *format_F2_r: fmt.Println("F2_r", val)
|
||||
case *format_F2_rn: fmt.Println("F2_rn", val)
|
||||
case *format_F2_rr: fmt.Println("F2_rr", val)
|
||||
case *format_F3_m: fmt.Println("F3_m", val)
|
||||
case *format_F4_m: fmt.Println("F4_m", val)
|
||||
case *format_D: fmt.Println("D", val)
|
||||
case *format_D_n: fmt.Println("D_n", val)
|
||||
case *format_M_r: fmt.Println("M_r", val)
|
||||
case *format_M_i: fmt.Println("M_i", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pregledovalnik bere vhodne vrstice in jih razgradi na posamezne enote.
|
||||
// Razpoznane elemente okvalificira (oznaka / mnemonik / operand / komentar)
|
||||
// //<zbirniski stavek> ::== [<oznaka stavka>] <ločilo> <mnemonik> <ločilo> {<operand> <ločilo>} [<komentar>]
|
||||
func main() {
|
||||
inputbyte, err := os.ReadFile("input.asm")
|
||||
if err != nil {
|
||||
fmt.Println("Error reading input file: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
input := string(inputbyte)
|
||||
pattern := regexp.MustCompile(`.*\n`)
|
||||
matches := pattern.FindAllString(input, -1)
|
||||
var AST []ukaz
|
||||
for _, el := range matches {
|
||||
if remove_comments_and_empty_lines(el) {
|
||||
continue
|
||||
}
|
||||
if check_D(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_D_n(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_M_r(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_M_i(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F1(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F2_n(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F2_r(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F2_rn(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F2_rr(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F3_m(el, &AST) {
|
||||
continue
|
||||
}
|
||||
if check_F4_m(el, &AST) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
prvi_prehod(&AST)
|
||||
//izpis(&AST)
|
||||
/*for k, v := range simbolna_tabela {
|
||||
fmt.Printf("k: %s v: %x\n", k, v)
|
||||
}*/
|
||||
drugi_prehod(&AST)
|
||||
//izpis(&AST)
|
||||
generacija(&AST)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue