package main import ( "fmt" "os" "regexp" "strings" ) 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, } type ukaz interface { Temp() } func (f format_F1) Temp() {} func (f format_F2_n) Temp() {} func (f format_F2_r) Temp() {} func (f format_F2_rn) Temp() {} func (f format_F2_rr) Temp() {} 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 } type format_F2_n struct { oznaka string opcode int format int velikost int n string x bool // indeksno naslavljanje } type format_F2_r struct { oznaka string opcode int format int velikost int r1 string } type format_F2_rn struct { oznaka string opcode int format int velikost int r1 string n string x bool } type format_F2_rr struct { oznaka string opcode int format int velikost int r1 string r2 string } type format_F3 struct { oznaka string opcode int format int velikost int } type format_F3_m struct { oznaka string opcode int format int velikost int naslov string x bool } 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 ") nov_ukaz.opcode = ukazna_tabela[mnemonik]; //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]+)(, X)?[\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.x = true nov_ukaz.n = strings.TrimRight(temp, ",") } else { nov_ukaz.x = false 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]+`) nov_ukaz.opcode = ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")] 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]+)(, X)?[\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]+`) nov_ukaz.opcode = ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")] 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.x = true nov_ukaz.n = strings.TrimRight(temp, ",") } else { nov_ukaz.x = false 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]+`) nov_ukaz.opcode = ukazna_tabela[strings.Trim(re_op.FindString(el), "\t ")] 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 } // Pregledovalnik bere vhodne vrstice in jih razgradi na posamezne enote. // Razpoznane elemente okvalificira (oznaka / mnemonik / operand / komentar) // // ::== [] { } [] func main() { inputbyte, err := os.ReadFile("input_invalid.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_F1(el, &AST) { continue } // TODO !!! odstrani # in @ in x naslalvljaje od F2 formata, saj nima bitov, da to podpre 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 } //match_F2, err := regexp.MatchString(`(?m)^[A-Za-z_]*[\t ]+[A-Za-z_]+[\t ](((`+register+`), (`+register+`))|((`+register+`), (#?|@?)[0-9]+)|(`+register+`))[\t ]*(\..*)?$\n`, el) } }