feat(parser): read the TEXT and GLOBL operands the toolchain counts them
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
cea5db6964
commit
431d0d9b0b
3 files changed
+262
-31
No files matched your search
+31
-16
@@ -251,22 +251,35 @@ func (p *state) parseText(line []token.Token) {
|
||||
text.Name = sym
|
||||
rest = rest[n:]
|
||||
|
||||
// Consume the flags operand: everything between the symbol and the
|
||||
// frame '$' is one operand, which the toolchain evaluates to a single
|
||||
// integer (identifiers joined by '|', each a known textflag.h name,
|
||||
// literals and constant arithmetic beside them). A single trailing
|
||||
// comma is the separator that stood before the '$'.
|
||||
// The tail splits into the toolchain's comma-separated operands: with
|
||||
// two, the first is the flags expression and the last the frame; with
|
||||
// three or more, the toolchain's own complaint. One operand is the
|
||||
// frame alone, whatever it starts with, so a malformed frame takes the
|
||||
// frame diagnostic and never reads as flags.
|
||||
rest = skipComma(rest)
|
||||
text.Flags, text.FlagVal = p.evalFlags(flagsRun(rest), false)
|
||||
for len(rest) > 0 && rest[0].Kind != token.Dollar {
|
||||
rest = rest[1:]
|
||||
ops := splitOperands(rest)
|
||||
var frame []token.Token
|
||||
switch {
|
||||
case len(ops) >= 2:
|
||||
text.Flags, text.FlagVal = p.evalFlags(flagsRun(ops[0]), false)
|
||||
frame = ops[1]
|
||||
if len(ops) > 2 {
|
||||
p.errorf(line[0].Pos, "expect two or three operands for TEXT")
|
||||
}
|
||||
case len(ops) == 1:
|
||||
frame = ops[0]
|
||||
}
|
||||
if len(frame) > 0 && frame[0].Kind != token.Dollar {
|
||||
p.errorf(line[0].Pos, "TEXT frame size must be an immediate constant")
|
||||
frame = nil
|
||||
}
|
||||
|
||||
// Frame: $[-]number ; optional args: -number. The Go runtime writes
|
||||
// zero frames with an explicit sign ("$-0-24"), so the number may carry
|
||||
// one. Whatever remains after the header is the body and is parsed by
|
||||
// the caller.
|
||||
if len(rest) > 0 && rest[0].Kind == token.Dollar {
|
||||
if len(frame) > 0 && frame[0].Kind == token.Dollar {
|
||||
rest = frame
|
||||
n := 1
|
||||
neg := false
|
||||
if n < len(rest) && (rest[n].Kind == token.Minus || rest[n].Kind == token.Plus) {
|
||||
@@ -337,13 +350,15 @@ func (p *state) parseGlobl(line []token.Token) *ast.Globl {
|
||||
// operand as one constant expression, so every name is validated here
|
||||
// and the whole operand folds to g.FlagVal; Flags keeps the atoms as
|
||||
// written, the numeric spellings being data-side combinations the
|
||||
// link layer reads back.
|
||||
g.Flags, g.FlagVal = p.evalFlags(flagsRun(rest), true)
|
||||
for i, t := range rest {
|
||||
if t.Kind == token.Dollar {
|
||||
g.Size = parseOperand(rest[i:], false)
|
||||
break
|
||||
}
|
||||
// link layer reads back. The size is the last operand; a third
|
||||
// operand's excess is the toolchain's own silence.
|
||||
ops := splitOperands(rest)
|
||||
switch {
|
||||
case len(ops) >= 2:
|
||||
g.Flags, g.FlagVal = p.evalFlags(flagsRun(ops[0]), true)
|
||||
g.Size = parseOperand(ops[1], false)
|
||||
case len(ops) == 1:
|
||||
g.Size = parseOperand(ops[0], false)
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user