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() fmt.Println("H", 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 { fmt.Printf("T: %x, %x, %s\n", line_addr, line_len, line) line_len = el.Velikost() line = temp line_addr = el.GetAddr() } } fmt.Printf("T: %x, %x, %s\n", line_addr, line_len, line) for _, el := range M_tabela { fmt.Printf("M: %06x, %02x \n", el.odmik, el.dolzina) } fmt.Printf("END %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) // // ::== [] { } [] 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) }