diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 116 |
1 files changed, 70 insertions, 46 deletions
@@ -19,38 +19,38 @@ type ProgramState struct { IsMacro bool } -func parseFile(input_file_name string, input []byte, offset uint) ([]byte, error) { +func parseFile(inputFileName string, input []byte, offset uint) ([]byte, error) { state := ProgramState{ Labels: make(map[string]uint), Defs: make(map[string]any), IsMacro: false, } - _, err := firstPass(input_file_name, input, offset, &state) + _, err := firstPass(inputFileName, input, offset, &state) if err != nil { return nil, err } - return secondPass(input_file_name, input, offset, state) + return secondPass(inputFileName, input, offset, state) } func firstPass( - input_file_name string, + inputFileName string, input []byte, offset uint, state *ProgramState, ) ([]byte, error) { lines := strings.Split(string(input), "\n") - line_nb := 0 + lineNb := 0 result := []byte{} lastAbsoluteLabel := "" - for line_nb < len(lines) { - line := lines[line_nb] - line_parts := strings.Split(line, ";") - line = line_parts[0] - is_label_defined := strings.Contains(line, ":") + for lineNb < len(lines) { + line := lines[lineNb] + lineParts := strings.Split(line, ";") + line = lineParts[0] + isLabelDefined := strings.Contains(line, ":") - if is_label_defined { + if isLabelDefined { parts := strings.Split(line, ":") for _, label := range parts[:len(parts)-1] { label = strings.TrimSpace(strings.ToUpper(label)) @@ -58,8 +58,8 @@ func firstPass( if !isCharsetAllowed { return nil, fmt.Errorf( "File %s, line %d:\nLabel \"%s\" contains special characters. Only alphanumeric, dashes and underscores are allowed", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, label, ) } @@ -85,8 +85,8 @@ func firstPass( if _, ok := state.Labels[label]; ok { return nil, fmt.Errorf( "File %s, line %d:\nLabel %s is already defined", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, label, ) } @@ -108,82 +108,106 @@ func firstPass( // nil sets all the labels and defintion to 0 & thus, to not crash JR, the currentAddress should also be 0 if strings.HasPrefix(line, ".") { - err := MacroParse(line, lines, &result, state, &line_nb, true, offset) + err := MacroParse(line, lines, &result, state, &lineNb, true, offset, lastAbsoluteLabel) if err != nil { return nil, fmt.Errorf( "File %s, line %d (1st pass|macro):\n%w", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, err, ) } } else { - next_instruction, err := Instructions.Parse(&state.Labels, &state.Defs, state.IsMacro, true, 0, line) + nextInstruction, err := Instructions.Parse(&state.Labels, &state.Defs, state.IsMacro, true, 0, lastAbsoluteLabel, line) if err != nil { return nil, fmt.Errorf( "File %s, line %d (1st pass):\n%w", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, err, ) } - result = append(result, next_instruction...) + result = append(result, nextInstruction...) } - line_nb += 1 + lineNb += 1 } return result, nil } func secondPass( - input_file_name string, + inputFileName string, input []byte, offset uint, state ProgramState, ) ([]byte, error) { lines := strings.Split(string(input), "\n") - line_nb := 0 + lineNb := 0 result := []byte{} - for line_nb < len(lines) { - line := lines[line_nb] - line_parts := strings.Split(line, ";") - line = line_parts[0] - is_label_defined := strings.Contains(line, ":") + lastAbsoluteLabel := "" + for lineNb < len(lines) { + line := lines[lineNb] + lineParts := strings.Split(line, ";") + line = lineParts[0] + isLabelDefined := strings.Contains(line, ":") - if is_label_defined { + if isLabelDefined { parts := strings.Split(line, ":") line = parts[len(parts)-1] + + for _, label := range parts[:len(parts)-1] { + if !strings.HasPrefix(label, ".") { + labelParts := strings.Split(label, ".") + if len(labelParts) < 1 { + return nil, fmt.Errorf( + "Unknown issue while retrieving label absolute part ! (label: \"%s\")", + label, + ) + } + + lastAbsoluteLabel = labelParts[0] + } + } } line = strings.TrimSpace(line) if strings.HasPrefix(line, ".") { - err := MacroParse(line, lines, &result, &state, &line_nb, false, offset) + err := MacroParse( + line, + lines, + &result, + &state, + &lineNb, + false, + offset, + lastAbsoluteLabel, + ) if err != nil { return nil, fmt.Errorf( "File %s, line %d (2nd pass|macro):\n%w", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, err, ) } } else { - next_instruction, err := Instructions.Parse(&state.Labels, &state.Defs, state.IsMacro, false, uint16(uint(len(result))+offset), line) + nextInstruction, err := Instructions.Parse(&state.Labels, &state.Defs, state.IsMacro, false, uint16(uint(len(result))+offset), lastAbsoluteLabel, line) if err != nil { return nil, fmt.Errorf( "File %s, line %d (2nd pass): %w", - input_file_name, - line_nb+1, + inputFileName, + lineNb+1, err, ) } - result = append(result, next_instruction...) + result = append(result, nextInstruction...) } - line_nb += 1 + lineNb += 1 } return result, nil @@ -195,34 +219,34 @@ func main() { os.Exit(1) } - input_file_name := os.Args[1] - output_file_name := os.Args[2] + inputFileName := os.Args[1] + outputFileName := os.Args[2] - input_file, err := os.Open(input_file_name) + inputFile, err := os.Open(inputFileName) if err != nil { fmt.Fprintf(os.Stderr, "Error while opening input file: %s\n", err.Error()) os.Exit(1) } - input, err := io.ReadAll(input_file) + input, err := io.ReadAll(inputFile) if err != nil { fmt.Fprintf(os.Stderr, "Error while reading input file: %s\n", err.Error()) os.Exit(1) } - result, err := parseFile(input_file_name, input, 0) + result, err := parseFile(inputFileName, input, 0) if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) os.Exit(1) } - output_file, err := os.Create(output_file_name) + outputFile, err := os.Create(outputFileName) if err != nil { fmt.Fprintf(os.Stderr, "Error while opening output file: %s\n", err.Error()) os.Exit(1) } - _, err = output_file.Write(result) + _, err = outputFile.Write(result) if err != nil { fmt.Fprintf(os.Stderr, "Error while writing to output file: %s\n", err.Error()) os.Exit(1) |