diff options
author | Astatin <[email protected]> | 2025-03-07 23:54:34 +0900 |
---|---|---|
committer | Astatin <[email protected]> | 2025-03-07 23:54:34 +0900 |
commit | 8c60c8cf7acb3563b31d9d17ba1303efe3f0aa39 (patch) | |
tree | 33b15fcd30c9527de21547f6b6cf3943348a6b60 | |
parent | c2fb41b27cb4294520cd73aa3d81d51d0f969bf8 (diff) |
add high/low paramters modifiers, parameters to macros & print symbols to stdout
-rw-r--r-- | instructions.go | 10 | ||||
-rw-r--r-- | macros.go | 29 | ||||
-rw-r--r-- | main.go | 8 | ||||
-rw-r--r-- | parameters.go | 21 |
4 files changed, 60 insertions, 8 deletions
diff --git a/instructions.go b/instructions.go index ca3df54..66c6d97 100644 --- a/instructions.go +++ b/instructions.go @@ -522,6 +522,7 @@ func (set InstructionSet) Parse( params := words[1:] + var rejectedErrors error instruction_param_loop: for _, instrParam := range instruction { if !instrParam.Wildcard && len(instrParam.Types) != len(params) { @@ -544,6 +545,12 @@ instruction_param_loop: } parsed, err := paramType(accessibleLabels, lastAbsoluteLabel, defs, params[i]) if err != nil { + rejectedError := fmt.Errorf("\t[Rejected] Param Type %v: %w\n", paramType, err) + if rejectedErrors == nil { + rejectedErrors = rejectedError + } else { + rejectedErrors = fmt.Errorf("%w%w", rejectedErrors, rejectedError) + } continue instruction_param_loop } @@ -557,8 +564,9 @@ instruction_param_loop: return instrParam.Assembler(currentAddress, parsed_params) } return nil, fmt.Errorf( - "Instruction \"%s\" doesn't have a parameter set that can parse \"%s\"", + "Instruction \"%s\" doesn't have a parameter set that can parse \"%s\"\n%w", words[0], line, + rejectedErrors, ) } @@ -165,10 +165,14 @@ func MacroParse( state.Defs[name] = definedValue } else if macroName == ".MACRODEF" && !state.IsMacro { - if len(words) != 2 { - return fmt.Errorf(".MACRODEF should have one argument, followed by the definition") + if len(words) < 2 { + return fmt.Errorf(".MACRODEF should have at least one argument, followed by the definition") } definedMacroName := strings.ToUpper(words[1]) + definedMacroArguments := words[2:] + for i := range definedMacroArguments { + definedMacroArguments[i] = strings.ToUpper(definedMacroArguments[i]) + } (*lineNb) += 1 macroContent := []byte{} for *lineNb < len(lines) && strings.TrimSpace(strings.Split(lines[*lineNb], ";")[0]) != ".END" { @@ -176,6 +180,11 @@ func MacroParse( (*lineNb) += 1 } + parameterTypes := make([]ParamType, len(definedMacroArguments)) + for i := range definedMacroArguments { + parameterTypes[i] = Raw16 + } + if isFirstPass { if _, ok := MacroInstructions[definedMacroName]; ok { return fmt.Errorf("Macro %s is already defined", definedMacroName) @@ -183,11 +192,15 @@ func MacroParse( MacroInstructions["."+definedMacroName] = []InstructionParams{ { - Types: []ParamType{}, + Types: parameterTypes, Assembler: func(currentAddress uint16, args []uint16) ([]uint8, error) { + definitions := Clone(state.Defs) + for i, macroArg := range definedMacroArguments { + definitions[macroArg] = Raw16b(args[i]) + } state := ProgramState{ Labels: Clone(state.Labels), - Defs: Clone(state.Defs), + Defs: definitions, IsMacro: true, } new_instructions, err := firstPass("MACRO$"+definedMacroName, macroContent, 0, &state) @@ -201,11 +214,15 @@ func MacroParse( } else { MacroInstructions["."+definedMacroName] = []InstructionParams{ { - Types: []ParamType{}, + Types: parameterTypes, Assembler: func(currentAddress uint16, args []uint16) ([]uint8, error) { + definitions := Clone(state.Defs) + for i, macroArg := range definedMacroArguments { + definitions[macroArg] = Raw16b(args[i]) + } state := ProgramState{ Labels: Clone(state.Labels), - Defs: Clone(state.Defs), + Defs: definitions, IsMacro: true, } _, err := firstPass("MACRO$"+definedMacroName, macroContent, uint(currentAddress), &state) @@ -19,6 +19,12 @@ type ProgramState struct { IsMacro bool } +func printSymbols(labels map[string]uint) { + for key, value := range labels { + fmt.Printf("00:%04x %s\n", value, key) + } +} + func parseFile(inputFileName string, input []byte, offset uint) ([]byte, error) { state := ProgramState{ Labels: make(map[string]uint), @@ -30,6 +36,7 @@ func parseFile(inputFileName string, input []byte, offset uint) ([]byte, error) if err != nil { return nil, err } + printSymbols(state.Labels) return secondPass(inputFileName, input, offset, state) } @@ -159,6 +166,7 @@ func secondPass( line = parts[len(parts)-1] for _, label := range parts[:len(parts)-1] { + label = strings.TrimSpace(strings.ToUpper(label)) if !strings.HasPrefix(label, ".") { labelParts := strings.Split(label, ".") if len(labelParts) < 1 { diff --git a/parameters.go b/parameters.go index ac17f70..21930c2 100644 --- a/parameters.go +++ b/parameters.go @@ -73,7 +73,26 @@ func Reg16(_ *Labels, lastAbsoluteLabel string, _ *Definitions, param string) (u return 0, fmt.Errorf("Invalid reg16") } -func Raw8(_ *Labels, lastAbsoluteLabel string, defs *Definitions, param string) (uint16, error) { +func Raw8( + labels *Labels, + lastAbsoluteLabel string, + defs *Definitions, + param string, +) (uint16, error) { + if strings.HasPrefix(param, "high(") && strings.HasSuffix(param, ")") { + v, err := Raw16(labels, lastAbsoluteLabel, defs, param[5:len(param)-1]) + if err != nil { + return 0, err + } + return uint16(v >> 8), nil + } + if strings.HasPrefix(param, "low(") && strings.HasSuffix(param, ")") { + v, err := Raw16(labels, lastAbsoluteLabel, defs, param[4:len(param)-1]) + if err != nil { + return 0, err + } + return uint16(v & 0xff), nil + } if strings.HasPrefix(param, "$") { param = strings.ToUpper(strings.TrimPrefix(param, "$")) if res, err := strconv.ParseUint(param, 16, 16); err == nil { |