aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-03-07 23:54:34 +0900
committerAstatin <[email protected]>2025-03-07 23:54:34 +0900
commit8c60c8cf7acb3563b31d9d17ba1303efe3f0aa39 (patch)
tree33b15fcd30c9527de21547f6b6cf3943348a6b60
parentc2fb41b27cb4294520cd73aa3d81d51d0f969bf8 (diff)
add high/low paramters modifiers, parameters to macros & print symbols to stdout
-rw-r--r--instructions.go10
-rw-r--r--macros.go29
-rw-r--r--main.go8
-rw-r--r--parameters.go21
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,
)
}
diff --git a/macros.go b/macros.go
index bf91eaa..22c300f 100644
--- a/macros.go
+++ b/macros.go
@@ -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)
diff --git a/main.go b/main.go
index 7d289a0..546cfbc 100644
--- a/main.go
+++ b/main.go
@@ -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 {