drugi prehod 2.0

This commit is contained in:
aljazbrodar. 2026-01-17 11:22:35 +01:00
parent 504df9b8fd
commit dc71999c7d
12 changed files with 281 additions and 51 deletions

View file

@ -76,6 +76,12 @@ var ime_programa string
var lc_global int
var bazno_dovoljeno bool
var bazno_naslov int
var zacetni_naslov int
type ukaz interface {
GetOznaka() string
}
@ -146,6 +152,7 @@ type format_F3_m struct {
format int // 3
velikost int
naslov string
odmik int
x bool
b bool
p bool
@ -161,6 +168,7 @@ type format_F4_m struct {
format int // 4
velikost int
naslov string
odmik int
x bool
b bool
p bool
@ -203,7 +211,6 @@ type format_M_i struct {
format int // 9
velikost int
operand string
rezervacija int
lc int
}
@ -382,7 +389,7 @@ func check_F2_rr(el string, AST *[]ukaz) bool {
}
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)
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.")
}
@ -404,7 +411,7 @@ func check_F3_m(el string, AST *[]ukaz) bool {
}
nov_ukaz.opcode = val
// naslov
re_par1 := regexp.MustCompile(`[\t ]+[A-Za-z]+ ([A-Za-z]+|(#?|@?)[0-9+]+)`)
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
@ -416,8 +423,8 @@ func check_F3_m(el string, AST *[]ukaz) bool {
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
} else {
//temp
nov_ukaz.n = false
nov_ukaz.i = false
nov_ukaz.n = true
nov_ukaz.i = true
}
// indeksno naslavljanje
re_x := regexp.MustCompile(`(, X)[\t ]*(\..*)?\n`)
@ -435,7 +442,7 @@ func check_F3_m(el string, AST *[]ukaz) bool {
}
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)
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.")
}
@ -458,7 +465,7 @@ func check_F4_m(el string, AST *[]ukaz) bool {
}
nov_ukaz.opcode = val
// naslov
re_par1 := regexp.MustCompile(`[\t ]+\+[A-Za-z]+ ([A-Za-z]+|(#?|@?)[0-9+]+)`)
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
@ -469,8 +476,8 @@ func check_F4_m(el string, AST *[]ukaz) bool {
nov_ukaz.i = true
nov_ukaz.naslov = nov_ukaz.naslov[1:len(nov_ukaz.naslov)]
} else {
nov_ukaz.n = false
nov_ukaz.i = false
nov_ukaz.n = true
nov_ukaz.i = true
}
// indeksno naslavljanje
re_x := regexp.MustCompile(`(, X)[\t ]*(\..*)?\n`)
@ -586,13 +593,10 @@ func check_M_i(el string, AST *[]ukaz) bool {
}
re_ope := regexp.MustCompile(`[0-9]+`)
nova_direktiva.operand = re_ope.FindString(el)
operand_int, _ := strconv.Atoi(nova_direktiva.operand)
if nova_direktiva.ime == "WORD" {
nova_direktiva.velikost = 3
nova_direktiva.rezervacija = 3 * operand_int
} else {
nova_direktiva.velikost = 1
nova_direktiva.rezervacija = operand_int
}
//fmt.Println(el, nova_direktiva)
*AST = append(*AST, &nova_direktiva)
@ -605,32 +609,166 @@ func prvi_prehod(AST *[]ukaz) {
lc_global, _ = strconv.Atoi((*AST)[0].(*format_D_n).operand)
ime_programa = (*AST)[0].(*format_D_n).oznaka
for _, el := range *AST {
fmt.Println("lc_global", lc_global)
//fmt.Printf("lc_global '%x'\n", lc_global)
switch val := el.(type) {
case *format_F1: val.lc = lc_global
lc_global += 1
if val.oznaka != "" {
simbolna_tabela[val.oznaka] = lc_global
}
lc_global += val.velikost
case *format_F2_n: val.lc = lc_global
lc_global += 2
if val.oznaka != "" {
simbolna_tabela[val.oznaka] = lc_global
}
lc_global += val.velikost
case *format_F2_r: val.lc = lc_global
lc_global += 2
if val.oznaka != "" {
simbolna_tabela[val.oznaka] = lc_global
}
lc_global += val.velikost
case *format_F2_rn: val.lc = lc_global
lc_global += 2
if val.oznaka != "" {
simbolna_tabela[val.oznaka] = lc_global
}
lc_global += val.velikost
case *format_F2_rr: val.lc = lc_global
lc_global += 2
if val.oznaka != "" {
simbolna_tabela[val.oznaka] = lc_global
}
lc_global += val.velikost
case *format_F3_m: val.lc = lc_global
lc_global += 3
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
lc_global += 4
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
lc_global += val.rezervacija
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.odmik = st - (val.lc + val.velikost) //naslov - PC
} else if bazno_dovoljeno && st >= 0 && st <= 4095 {
val.odmik = st - bazno_naslov
} 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.odmik = st - (val.lc + val.velikost) //naslov - PC
} else if bazno_dovoljeno && st >= 0 && st <= 4095 {
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.odmik = naslov - (val.lc + val.velikost) //naslov - PC
} else if bazno_dovoljeno && naslov >= 0 && naslov <= 4095 {
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.odmik = naslov - (val.lc + val.velikost) //naslov - PC
//fmt.Printf("pc %x\n", val.odmik)
} else if bazno_dovoljeno && naslov >= 0 && naslov <= 4095 {
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 {
if val.n && !val.i {
} else if !val.n && val.i {
} else if val.n && val.i {
}
} else {
if val.n && !val.i {
} else if !val.n && val.i {
} else if val.n && val.i {
}
}
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 izpis(AST *[]ukaz) {
for _, el := range *AST {
switch val := el.(type) {
@ -703,6 +841,10 @@ func main() {
}
}
prvi_prehod(&AST)
izpis(&AST)
//drugi_prehod()
//izpis(&AST)
/*for k, v := range simbolna_tabela {
fmt.Printf("k: %s v: %x\n", k, v)
}*/
drugi_prehod(&AST)
//izpis(&AST)
}