mirror of
https://github.com/golang/go
synced 2024-11-12 09:50:21 -07:00
cmd/internal/asm: delete
Updates #10510. Change-Id: Ib4d39943969d18517b373292b83d87650d5df12a Reviewed-on: https://go-review.googlesource.com/12787 Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
ba0c142d32
commit
861af80458
@ -1,307 +0,0 @@
|
||||
// Inferno utils/6a/a.h and lex.c.
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6a/a.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6a/lex.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Package asm holds code shared among the assemblers.
|
||||
package asm
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cmd/internal/obj"
|
||||
)
|
||||
|
||||
// Initialized by client.
|
||||
var (
|
||||
LSCONST int
|
||||
LCONST int
|
||||
LFCONST int
|
||||
LNAME int
|
||||
LVAR int
|
||||
LLAB int
|
||||
|
||||
Thechar rune
|
||||
Thestring string
|
||||
Thelinkarch *obj.LinkArch
|
||||
|
||||
Arches map[string]*obj.LinkArch
|
||||
|
||||
Cclean func()
|
||||
Yyparse func()
|
||||
Syminit func(*Sym)
|
||||
|
||||
Lexinit []Lextab
|
||||
)
|
||||
|
||||
type Lextab struct {
|
||||
Name string
|
||||
Type int
|
||||
Value int64
|
||||
}
|
||||
|
||||
const (
|
||||
MAXALIGN = 7
|
||||
FPCHIP = 1
|
||||
NSYMB = 500
|
||||
BUFSIZ = 8192
|
||||
HISTSZ = 20
|
||||
EOF = -1
|
||||
IGN = -2
|
||||
NHASH = 503
|
||||
NMACRO = 10
|
||||
)
|
||||
|
||||
const (
|
||||
CLAST = iota
|
||||
CMACARG
|
||||
CMACRO
|
||||
CPREPROC
|
||||
)
|
||||
|
||||
type Macro struct {
|
||||
Text string
|
||||
Narg int
|
||||
Dots bool
|
||||
}
|
||||
|
||||
type Sym struct {
|
||||
Link *Sym
|
||||
Ref *Ref
|
||||
Macro *Macro
|
||||
Value int64
|
||||
Type int
|
||||
Name string
|
||||
Labelname string
|
||||
Sym int8
|
||||
}
|
||||
|
||||
type Ref struct {
|
||||
Class int
|
||||
}
|
||||
|
||||
type Io struct {
|
||||
Link *Io
|
||||
P []byte
|
||||
F *os.File
|
||||
B [1024]byte
|
||||
}
|
||||
|
||||
var fi struct {
|
||||
P []byte
|
||||
}
|
||||
|
||||
var (
|
||||
debug [256]int
|
||||
hash = map[string]*Sym{}
|
||||
Dlist []string
|
||||
newflag int
|
||||
hunk string
|
||||
include []string
|
||||
iofree *Io
|
||||
ionext *Io
|
||||
iostack *Io
|
||||
Lineno int32
|
||||
nerrors int
|
||||
nhunk int32
|
||||
ninclude int
|
||||
nsymb int32
|
||||
nullgen obj.Addr
|
||||
outfile string
|
||||
Pass int
|
||||
PC int32
|
||||
peekc int = IGN
|
||||
sym int
|
||||
symb string
|
||||
thunk int32
|
||||
obuf obj.Biobuf
|
||||
Ctxt *obj.Link
|
||||
bstdout obj.Biobuf
|
||||
)
|
||||
|
||||
func dodef(p string) {
|
||||
Dlist = append(Dlist, p)
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Printf("usage: %ca [options] file.c...\n", Thechar)
|
||||
flag.PrintDefaults()
|
||||
errorexit()
|
||||
}
|
||||
|
||||
func Main() {
|
||||
// Allow GOARCH=Thestring or GOARCH=Thestringsuffix,
|
||||
// but not other values.
|
||||
p := obj.Getgoarch()
|
||||
|
||||
if !strings.HasPrefix(p, Thestring) {
|
||||
log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p)
|
||||
}
|
||||
if p != Thestring {
|
||||
Thelinkarch = Arches[p]
|
||||
if Thelinkarch == nil {
|
||||
log.Fatalf("unknown arch %s", p)
|
||||
}
|
||||
}
|
||||
|
||||
Ctxt = obj.Linknew(Thelinkarch)
|
||||
Ctxt.Diag = Yyerror
|
||||
Ctxt.Bso = &bstdout
|
||||
Ctxt.Enforce_data_order = 1
|
||||
bstdout = *obj.Binitw(os.Stdout)
|
||||
|
||||
debug = [256]int{}
|
||||
cinit()
|
||||
outfile = ""
|
||||
setinclude(".")
|
||||
|
||||
flag.Var(flagFn(dodef), "D", "name[=value]: add #define")
|
||||
flag.Var(flagFn(setinclude), "I", "dir: add dir to include path")
|
||||
flag.Var((*count)(&debug['S']), "S", "print assembly and machine code")
|
||||
flag.Var((*count)(&debug['m']), "m", "debug preprocessor macros")
|
||||
flag.StringVar(&outfile, "o", "", "file: set output file")
|
||||
flag.StringVar(&Ctxt.LineHist.TrimPathPrefix, "trimpath", "", "prefix: remove prefix from recorded source file paths")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
Ctxt.Debugasm = int32(debug['S'])
|
||||
|
||||
if flag.NArg() < 1 {
|
||||
usage()
|
||||
}
|
||||
if flag.NArg() > 1 {
|
||||
fmt.Printf("can't assemble multiple files\n")
|
||||
errorexit()
|
||||
}
|
||||
|
||||
if assemble(flag.Arg(0)) != 0 {
|
||||
errorexit()
|
||||
}
|
||||
bstdout.Flush()
|
||||
if nerrors > 0 {
|
||||
errorexit()
|
||||
}
|
||||
}
|
||||
|
||||
func assemble(file string) int {
|
||||
if outfile == "" {
|
||||
outfile = strings.TrimSuffix(filepath.Base(file), ".s") + "." + string(Thechar)
|
||||
}
|
||||
|
||||
of, err := os.Create(outfile)
|
||||
if err != nil {
|
||||
Yyerror("%ca: cannot create %s", Thechar, outfile)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
obuf = *obj.Binitw(of)
|
||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion())
|
||||
fmt.Fprintf(&obuf, "!\n")
|
||||
|
||||
var i int
|
||||
for Pass = 1; Pass <= 2; Pass++ {
|
||||
pinit(file)
|
||||
for i = 0; i < len(Dlist); i++ {
|
||||
dodefine(Dlist[i])
|
||||
}
|
||||
Yyparse()
|
||||
Cclean()
|
||||
if nerrors != 0 {
|
||||
return nerrors
|
||||
}
|
||||
}
|
||||
|
||||
obj.Writeobjdirect(Ctxt, &obuf)
|
||||
obuf.Flush()
|
||||
return 0
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
for i := 0; i < len(Lexinit); i++ {
|
||||
s := Lookup(Lexinit[i].Name)
|
||||
if s.Type != LNAME {
|
||||
Yyerror("double initialization %s", Lexinit[i].Name)
|
||||
}
|
||||
s.Type = Lexinit[i].Type
|
||||
s.Value = Lexinit[i].Value
|
||||
}
|
||||
}
|
||||
|
||||
func syminit(s *Sym) {
|
||||
s.Type = LNAME
|
||||
s.Value = 0
|
||||
}
|
||||
|
||||
type flagFn func(string)
|
||||
|
||||
func (flagFn) String() string {
|
||||
return "<arg>"
|
||||
}
|
||||
|
||||
func (f flagFn) Set(s string) error {
|
||||
f(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
type yyImpl struct{}
|
||||
|
||||
// count is a flag.Value that is like a flag.Bool and a flag.Int.
|
||||
// If used as -name, it increments the count, but -name=x sets the count.
|
||||
// Used for verbose flag -v.
|
||||
type count int
|
||||
|
||||
func (c *count) String() string {
|
||||
return fmt.Sprint(int(*c))
|
||||
}
|
||||
|
||||
func (c *count) Set(s string) error {
|
||||
switch s {
|
||||
case "true":
|
||||
*c++
|
||||
case "false":
|
||||
*c = 0
|
||||
default:
|
||||
n, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid count %q", s)
|
||||
}
|
||||
*c = count(n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *count) IsBoolFlag() bool {
|
||||
return true
|
||||
}
|
@ -1,710 +0,0 @@
|
||||
// Inferno utils/cc/lexbody
|
||||
// http://code.Google.Com/p/inferno-os/source/browse/utils/cc/lexbody
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.Vitanuova.Com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package asm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"cmd/internal/obj"
|
||||
)
|
||||
|
||||
/*
|
||||
* common code for all the assemblers
|
||||
*/
|
||||
func pragpack() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragvararg() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragcgo(name string) {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragfpround() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragtextflag() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragdataflag() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragprofile() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func pragincomplete() {
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
}
|
||||
|
||||
func setinclude(p string) {
|
||||
if p == "" {
|
||||
return
|
||||
}
|
||||
for i := 1; i < len(include); i++ {
|
||||
if p == include[i] {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
include = append(include, p)
|
||||
}
|
||||
|
||||
func errorexit() {
|
||||
bstdout.Flush()
|
||||
if outfile != "" {
|
||||
os.Remove(outfile)
|
||||
}
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func pushio() {
|
||||
i := iostack
|
||||
if i == nil {
|
||||
Yyerror("botch in pushio")
|
||||
errorexit()
|
||||
}
|
||||
|
||||
i.P = fi.P
|
||||
}
|
||||
|
||||
func newio() {
|
||||
var pushdepth int = 0
|
||||
|
||||
i := iofree
|
||||
if i == nil {
|
||||
pushdepth++
|
||||
if pushdepth > 1000 {
|
||||
Yyerror("macro/io expansion too deep")
|
||||
errorexit()
|
||||
}
|
||||
i = new(Io)
|
||||
} else {
|
||||
iofree = i.Link
|
||||
}
|
||||
i.F = nil
|
||||
i.P = nil
|
||||
ionext = i
|
||||
}
|
||||
|
||||
func newfile(s string, f *os.File) {
|
||||
i := ionext
|
||||
i.Link = iostack
|
||||
iostack = i
|
||||
i.F = f
|
||||
if f == nil {
|
||||
var err error
|
||||
i.F, err = os.Open(s)
|
||||
if err != nil {
|
||||
Yyerror("%ca: %v", Thechar, err)
|
||||
errorexit()
|
||||
}
|
||||
}
|
||||
|
||||
fi.P = nil
|
||||
Ctxt.LineHist.Push(int(Lineno), s)
|
||||
}
|
||||
|
||||
var thetext *obj.LSym
|
||||
|
||||
func Settext(s *obj.LSym) {
|
||||
thetext = s
|
||||
}
|
||||
|
||||
func LabelLookup(s *Sym) *Sym {
|
||||
if thetext == nil {
|
||||
s.Labelname = s.Name
|
||||
return s
|
||||
}
|
||||
|
||||
p := string(fmt.Sprintf("%s.%s", thetext.Name, s.Name))
|
||||
lab := Lookup(p)
|
||||
|
||||
lab.Labelname = s.Name
|
||||
return lab
|
||||
}
|
||||
|
||||
func Lookup(symb string) *Sym {
|
||||
// turn leading · into ""·
|
||||
if strings.HasPrefix(symb, "·") {
|
||||
symb = `""` + symb
|
||||
}
|
||||
|
||||
// turn · (U+00B7) into .
|
||||
// turn ∕ (U+2215) into /
|
||||
symb = strings.Replace(symb, "·", ".", -1)
|
||||
symb = strings.Replace(symb, "∕", "/", -1)
|
||||
|
||||
s := hash[symb]
|
||||
if s != nil {
|
||||
return s
|
||||
}
|
||||
|
||||
s = new(Sym)
|
||||
s.Name = symb
|
||||
syminit(s)
|
||||
hash[symb] = s
|
||||
return s
|
||||
}
|
||||
|
||||
func isalnum(c int) bool {
|
||||
return isalpha(c) || isdigit(c)
|
||||
}
|
||||
|
||||
func isalpha(c int) bool {
|
||||
return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
|
||||
}
|
||||
|
||||
func isspace(c int) bool {
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n'
|
||||
}
|
||||
|
||||
func ISALPHA(c int) bool {
|
||||
if isalpha(c) {
|
||||
return true
|
||||
}
|
||||
if c >= utf8.RuneSelf {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var yybuf bytes.Buffer
|
||||
|
||||
func (yyImpl) Error(s string) {
|
||||
Yyerror("%s", s)
|
||||
}
|
||||
|
||||
type Yylval struct {
|
||||
Sym *Sym
|
||||
Lval int64
|
||||
Sval string
|
||||
Dval float64
|
||||
}
|
||||
|
||||
func Yylex(yylval *Yylval) int {
|
||||
var c1 int
|
||||
var s *Sym
|
||||
|
||||
c := peekc
|
||||
if c != IGN {
|
||||
peekc = IGN
|
||||
goto l1
|
||||
}
|
||||
|
||||
l0:
|
||||
c = GETC()
|
||||
|
||||
l1:
|
||||
if c == EOF {
|
||||
peekc = EOF
|
||||
return -1
|
||||
}
|
||||
|
||||
if isspace(c) {
|
||||
if c == '\n' {
|
||||
Lineno++
|
||||
return ';'
|
||||
}
|
||||
|
||||
goto l0
|
||||
}
|
||||
|
||||
if ISALPHA(c) {
|
||||
yybuf.Reset()
|
||||
goto aloop
|
||||
}
|
||||
if isdigit(c) {
|
||||
yybuf.Reset()
|
||||
if c != '0' {
|
||||
goto dc
|
||||
}
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
c1 = 3
|
||||
if c == 'x' || c == 'X' {
|
||||
c1 = 4
|
||||
c = GETC()
|
||||
} else if c < '0' || c > '7' {
|
||||
goto dc
|
||||
}
|
||||
yylval.Lval = 0
|
||||
for {
|
||||
if c >= '0' && c <= '9' {
|
||||
if c > '7' && c1 == 3 {
|
||||
break
|
||||
}
|
||||
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
||||
yylval.Lval += int64(c) - '0'
|
||||
c = GETC()
|
||||
continue
|
||||
}
|
||||
|
||||
if c1 == 3 {
|
||||
break
|
||||
}
|
||||
if c >= 'A' && c <= 'F' {
|
||||
c += 'a' - 'A'
|
||||
}
|
||||
if c >= 'a' && c <= 'f' {
|
||||
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
||||
yylval.Lval += int64(c) - 'a' + 10
|
||||
c = GETC()
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
goto ncu
|
||||
}
|
||||
switch c {
|
||||
case '\n':
|
||||
Lineno++
|
||||
return ';'
|
||||
|
||||
case '#':
|
||||
domacro()
|
||||
goto l0
|
||||
|
||||
case '.':
|
||||
c = GETC()
|
||||
if ISALPHA(c) {
|
||||
yybuf.Reset()
|
||||
yybuf.WriteByte('.')
|
||||
goto aloop
|
||||
}
|
||||
|
||||
if isdigit(c) {
|
||||
yybuf.Reset()
|
||||
yybuf.WriteByte('.')
|
||||
goto casedot
|
||||
}
|
||||
|
||||
peekc = c
|
||||
return '.'
|
||||
|
||||
case '_',
|
||||
'@':
|
||||
yybuf.Reset()
|
||||
goto aloop
|
||||
|
||||
case '"':
|
||||
var buf bytes.Buffer
|
||||
c1 = 0
|
||||
for {
|
||||
c = escchar('"')
|
||||
if c == EOF {
|
||||
break
|
||||
}
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
yylval.Sval = buf.String()
|
||||
return LSCONST
|
||||
|
||||
case '\'':
|
||||
c = escchar('\'')
|
||||
if c == EOF {
|
||||
c = '\''
|
||||
}
|
||||
if escchar('\'') != EOF {
|
||||
Yyerror("missing '")
|
||||
}
|
||||
yylval.Lval = int64(c)
|
||||
return LCONST
|
||||
|
||||
case '/':
|
||||
c1 = GETC()
|
||||
if c1 == '/' {
|
||||
for {
|
||||
c = GETC()
|
||||
if c == '\n' {
|
||||
goto l1
|
||||
}
|
||||
if c == EOF {
|
||||
Yyerror("eof in comment")
|
||||
errorexit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c1 == '*' {
|
||||
for {
|
||||
c = GETC()
|
||||
for c == '*' {
|
||||
c = GETC()
|
||||
if c == '/' {
|
||||
goto l0
|
||||
}
|
||||
}
|
||||
|
||||
if c == EOF {
|
||||
Yyerror("eof in comment")
|
||||
errorexit()
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
Lineno++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return int(c)
|
||||
}
|
||||
|
||||
peekc = c1
|
||||
return int(c)
|
||||
|
||||
casedot:
|
||||
for {
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
if !(isdigit(c)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if c == 'e' || c == 'E' {
|
||||
goto casee
|
||||
}
|
||||
goto caseout
|
||||
|
||||
casee:
|
||||
yybuf.WriteByte('e')
|
||||
c = GETC()
|
||||
if c == '+' || c == '-' {
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
}
|
||||
|
||||
for isdigit(c) {
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
}
|
||||
|
||||
caseout:
|
||||
peekc = c
|
||||
if FPCHIP != 0 /*TypeKind(100016)*/ {
|
||||
last = yybuf.String()
|
||||
yylval.Dval = atof(last)
|
||||
return LFCONST
|
||||
}
|
||||
|
||||
Yyerror("assembler cannot interpret fp constants")
|
||||
yylval.Lval = 1
|
||||
return LCONST
|
||||
|
||||
aloop:
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
if ISALPHA(c) || isdigit(c) || c == '_' || c == '$' {
|
||||
goto aloop
|
||||
}
|
||||
peekc = c
|
||||
last = yybuf.String()
|
||||
s = Lookup(last)
|
||||
if s.Macro != nil {
|
||||
newio()
|
||||
ionext.P = macexpand(s)
|
||||
pushio()
|
||||
ionext.Link = iostack
|
||||
iostack = ionext
|
||||
fi.P = ionext.P
|
||||
if peekc != IGN {
|
||||
fi.P = append(fi.P, byte(peekc))
|
||||
peekc = IGN
|
||||
}
|
||||
|
||||
goto l0
|
||||
}
|
||||
|
||||
if s.Type == 0 {
|
||||
s.Type = LNAME
|
||||
}
|
||||
if s.Type == LNAME || s.Type == LVAR || s.Type == LLAB {
|
||||
yylval.Sym = s
|
||||
yylval.Sval = last
|
||||
return int(s.Type)
|
||||
}
|
||||
|
||||
yylval.Lval = s.Value
|
||||
yylval.Sval = last
|
||||
return int(s.Type)
|
||||
|
||||
dc:
|
||||
for {
|
||||
if !(isdigit(c)) {
|
||||
break
|
||||
}
|
||||
yybuf.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
}
|
||||
|
||||
if c == '.' {
|
||||
goto casedot
|
||||
}
|
||||
if c == 'e' || c == 'E' {
|
||||
goto casee
|
||||
}
|
||||
last = yybuf.String()
|
||||
yylval.Lval = strtoll(last, nil, 10)
|
||||
|
||||
ncu:
|
||||
for c == 'U' || c == 'u' || c == 'l' || c == 'L' {
|
||||
c = GETC()
|
||||
}
|
||||
peekc = c
|
||||
return LCONST
|
||||
}
|
||||
|
||||
func getc() int {
|
||||
c := peekc
|
||||
if c != IGN {
|
||||
peekc = IGN
|
||||
if c == '\n' {
|
||||
Lineno++
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
c = GETC()
|
||||
if c == '\n' {
|
||||
Lineno++
|
||||
}
|
||||
if c == EOF {
|
||||
Yyerror("End of file")
|
||||
errorexit()
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func getnsc() int {
|
||||
var c int
|
||||
|
||||
for {
|
||||
c = getc()
|
||||
if !isspace(c) || c == '\n' {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unget(c int) {
|
||||
peekc = c
|
||||
if c == '\n' {
|
||||
Lineno--
|
||||
}
|
||||
}
|
||||
|
||||
func escchar(e int) int {
|
||||
var l int
|
||||
|
||||
loop:
|
||||
c := getc()
|
||||
if c == '\n' {
|
||||
Yyerror("newline in string")
|
||||
return EOF
|
||||
}
|
||||
|
||||
if c != '\\' {
|
||||
if c == e {
|
||||
return EOF
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
c = getc()
|
||||
if c >= '0' && c <= '7' {
|
||||
l = c - '0'
|
||||
c = getc()
|
||||
if c >= '0' && c <= '7' {
|
||||
l = l*8 + c - '0'
|
||||
c = getc()
|
||||
if c >= '0' && c <= '7' {
|
||||
l = l*8 + c - '0'
|
||||
return l
|
||||
}
|
||||
}
|
||||
|
||||
peekc = c
|
||||
unget(c)
|
||||
return l
|
||||
}
|
||||
|
||||
switch c {
|
||||
case '\n':
|
||||
goto loop
|
||||
case 'n':
|
||||
return '\n'
|
||||
case 't':
|
||||
return '\t'
|
||||
case 'b':
|
||||
return '\b'
|
||||
case 'r':
|
||||
return '\r'
|
||||
case 'f':
|
||||
return '\f'
|
||||
case 'a':
|
||||
return 0x07
|
||||
case 'v':
|
||||
return 0x0b
|
||||
case 'z':
|
||||
return 0x00
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func pinit(f string) {
|
||||
Lineno = 1
|
||||
newio()
|
||||
newfile(f, nil)
|
||||
PC = 0
|
||||
peekc = IGN
|
||||
sym = 1
|
||||
for _, s := range hash {
|
||||
s.Macro = nil
|
||||
}
|
||||
}
|
||||
|
||||
func filbuf() int {
|
||||
var n int
|
||||
|
||||
loop:
|
||||
i := iostack
|
||||
if i == nil {
|
||||
return EOF
|
||||
}
|
||||
if i.F == nil {
|
||||
goto pop
|
||||
}
|
||||
n, _ = i.F.Read(i.B[:])
|
||||
if n == 0 {
|
||||
i.F.Close()
|
||||
Ctxt.LineHist.Pop(int(Lineno))
|
||||
goto pop
|
||||
}
|
||||
fi.P = i.B[1:n]
|
||||
return int(i.B[0]) & 0xff
|
||||
|
||||
pop:
|
||||
iostack = i.Link
|
||||
i.Link = iofree
|
||||
iofree = i
|
||||
i = iostack
|
||||
if i == nil {
|
||||
return EOF
|
||||
}
|
||||
fi.P = i.P
|
||||
if len(fi.P) == 0 {
|
||||
goto loop
|
||||
}
|
||||
tmp8 := fi.P
|
||||
fi.P = fi.P[1:]
|
||||
return int(tmp8[0]) & 0xff
|
||||
}
|
||||
|
||||
var last string
|
||||
|
||||
func Yyerror(a string, args ...interface{}) {
|
||||
/*
|
||||
* hack to intercept message from yaccpar
|
||||
*/
|
||||
if a == "syntax error" || len(args) == 1 && a == "%s" && args[0] == "syntax error" {
|
||||
Yyerror("syntax error, last name: %s", last)
|
||||
return
|
||||
}
|
||||
|
||||
prfile(Lineno)
|
||||
fmt.Printf("%s\n", fmt.Sprintf(a, args...))
|
||||
nerrors++
|
||||
if nerrors > 10 {
|
||||
fmt.Printf("too many errors\n")
|
||||
errorexit()
|
||||
}
|
||||
}
|
||||
|
||||
func prfile(l int32) {
|
||||
obj.Linkprfile(Ctxt, int(l))
|
||||
}
|
||||
|
||||
func GETC() int {
|
||||
if len(fi.P) == 0 {
|
||||
return filbuf()
|
||||
}
|
||||
c := int(fi.P[0])
|
||||
fi.P = fi.P[1:]
|
||||
return c
|
||||
}
|
||||
|
||||
func isdigit(c int) bool {
|
||||
return '0' <= c && c <= '9'
|
||||
}
|
||||
|
||||
func strtoll(s string, p *byte, base int) int64 {
|
||||
if p != nil {
|
||||
panic("strtoll")
|
||||
}
|
||||
n, err := strconv.ParseInt(s, base, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func atof(s string) float64 {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return f
|
||||
}
|
@ -1,855 +0,0 @@
|
||||
// Inferno utils/cc/macbody
|
||||
// http://code.Google.Com/p/inferno-os/source/browse/utils/cc/macbody
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.Vitanuova.Com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package asm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
VARMAC = 0x80
|
||||
)
|
||||
|
||||
func getnsn() int32 {
|
||||
c := getnsc()
|
||||
if c < '0' || c > '9' {
|
||||
return -1
|
||||
}
|
||||
n := int32(0)
|
||||
for c >= '0' && c <= '9' {
|
||||
n = n*10 + int32(c) - '0'
|
||||
c = getc()
|
||||
}
|
||||
|
||||
unget(c)
|
||||
return n
|
||||
}
|
||||
|
||||
func getsym() *Sym {
|
||||
c := getnsc()
|
||||
if !isalpha(c) && c != '_' && c < 0x80 {
|
||||
unget(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
for {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if isalnum(c) || c == '_' || c >= 0x80 {
|
||||
continue
|
||||
}
|
||||
unget(c)
|
||||
break
|
||||
}
|
||||
last = buf.String()
|
||||
return Lookup(last)
|
||||
}
|
||||
|
||||
func getsymdots(dots *int) *Sym {
|
||||
s := getsym()
|
||||
if s != nil {
|
||||
return s
|
||||
}
|
||||
|
||||
c := getnsc()
|
||||
if c != '.' {
|
||||
unget(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
if getc() != '.' || getc() != '.' {
|
||||
Yyerror("bad dots in macro")
|
||||
}
|
||||
*dots = 1
|
||||
return Lookup("__VA_ARGS__")
|
||||
}
|
||||
|
||||
func getcom() int {
|
||||
var c int
|
||||
|
||||
for {
|
||||
c = getnsc()
|
||||
if c != '/' {
|
||||
break
|
||||
}
|
||||
c = getc()
|
||||
if c == '/' {
|
||||
for c != '\n' {
|
||||
c = getc()
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if c != '*' {
|
||||
break
|
||||
}
|
||||
c = getc()
|
||||
for {
|
||||
if c == '*' {
|
||||
c = getc()
|
||||
if c != '/' {
|
||||
continue
|
||||
}
|
||||
c = getc()
|
||||
break
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
Yyerror("comment across newline")
|
||||
break
|
||||
}
|
||||
|
||||
c = getc()
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func dodefine(cp string) {
|
||||
var s *Sym
|
||||
|
||||
if i := strings.Index(cp, "="); i >= 0 {
|
||||
p := cp[i+1:]
|
||||
cp = cp[:i]
|
||||
s = Lookup(cp)
|
||||
s.Macro = &Macro{Text: p}
|
||||
} else {
|
||||
s = Lookup(cp)
|
||||
s.Macro = &Macro{Text: "1"}
|
||||
}
|
||||
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#define (-D) %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
}
|
||||
|
||||
var mactab = []struct {
|
||||
Macname string
|
||||
Macf func()
|
||||
}{
|
||||
{"ifdef", nil}, /* macif(0) */
|
||||
{"ifndef", nil}, /* macif(1) */
|
||||
{"else", nil}, /* macif(2) */
|
||||
{"line", maclin},
|
||||
{"define", macdef},
|
||||
{"include", macinc},
|
||||
{"undef", macund},
|
||||
{"pragma", macprag},
|
||||
{"endif", macend},
|
||||
}
|
||||
|
||||
func domacro() {
|
||||
s := getsym()
|
||||
if s == nil {
|
||||
s = Lookup("endif")
|
||||
}
|
||||
for i := 0; i < len(mactab); i++ {
|
||||
if s.Name == mactab[i].Macname {
|
||||
if mactab[i].Macf != nil {
|
||||
mactab[i].Macf()
|
||||
} else {
|
||||
macif(i)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Yyerror("unknown #: %s", s.Name)
|
||||
macend()
|
||||
}
|
||||
|
||||
func macund() {
|
||||
s := getsym()
|
||||
macend()
|
||||
if s == nil {
|
||||
Yyerror("syntax in #undef")
|
||||
return
|
||||
}
|
||||
|
||||
s.Macro = nil
|
||||
}
|
||||
|
||||
const (
|
||||
NARG = 25
|
||||
)
|
||||
|
||||
func macdef() {
|
||||
var args [NARG]string
|
||||
var n int
|
||||
var i int
|
||||
var c int
|
||||
var dots int
|
||||
var ischr int
|
||||
var base bytes.Buffer
|
||||
|
||||
s := getsym()
|
||||
if s == nil {
|
||||
goto bad
|
||||
}
|
||||
if s.Macro != nil {
|
||||
Yyerror("macro redefined: %s", s.Name)
|
||||
}
|
||||
c = getc()
|
||||
n = -1
|
||||
dots = 0
|
||||
if c == '(' {
|
||||
n++
|
||||
c = getnsc()
|
||||
if c != ')' {
|
||||
unget(c)
|
||||
var a *Sym
|
||||
var c int
|
||||
for {
|
||||
a = getsymdots(&dots)
|
||||
if a == nil {
|
||||
goto bad
|
||||
}
|
||||
if n >= NARG {
|
||||
Yyerror("too many arguments in #define: %s", s.Name)
|
||||
goto bad
|
||||
}
|
||||
|
||||
args[n] = a.Name
|
||||
n++
|
||||
c = getnsc()
|
||||
if c == ')' {
|
||||
break
|
||||
}
|
||||
if c != ',' || dots != 0 {
|
||||
goto bad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c = getc()
|
||||
}
|
||||
|
||||
if isspace(c) {
|
||||
if c != '\n' {
|
||||
c = getnsc()
|
||||
}
|
||||
}
|
||||
ischr = 0
|
||||
for {
|
||||
if isalpha(c) || c == '_' {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
for isalnum(c) || c == '_' {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
}
|
||||
|
||||
symb := buf.String()
|
||||
for i = 0; i < n; i++ {
|
||||
if symb == args[i] {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i >= n {
|
||||
base.WriteString(symb)
|
||||
continue
|
||||
}
|
||||
|
||||
base.WriteByte('#')
|
||||
base.WriteByte(byte('a' + i))
|
||||
continue
|
||||
}
|
||||
|
||||
if ischr != 0 {
|
||||
if c == '\\' {
|
||||
base.WriteByte(byte(c))
|
||||
c = getc()
|
||||
} else if c == ischr {
|
||||
ischr = 0
|
||||
}
|
||||
} else {
|
||||
if c == '"' || c == '\'' {
|
||||
base.WriteByte(byte(c))
|
||||
ischr = c
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '/' {
|
||||
c = getc()
|
||||
if c == '/' {
|
||||
c = getc()
|
||||
for {
|
||||
if c == '\n' {
|
||||
break
|
||||
}
|
||||
c = getc()
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '*' {
|
||||
c = getc()
|
||||
for {
|
||||
if c == '*' {
|
||||
c = getc()
|
||||
if c != '/' {
|
||||
continue
|
||||
}
|
||||
c = getc()
|
||||
break
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
Yyerror("comment and newline in define: %s", s.Name)
|
||||
break
|
||||
}
|
||||
|
||||
c = getc()
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
base.WriteByte('/')
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if c == '\\' {
|
||||
c = getc()
|
||||
if c == '\n' {
|
||||
c = getc()
|
||||
continue
|
||||
} else if c == '\r' {
|
||||
c = getc()
|
||||
if c == '\n' {
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
base.WriteByte('\\')
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
break
|
||||
}
|
||||
if c == '#' {
|
||||
if n > 0 {
|
||||
base.WriteByte(byte(c))
|
||||
}
|
||||
}
|
||||
|
||||
base.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
if c == '\n' {
|
||||
Lineno++
|
||||
}
|
||||
if c == -1 {
|
||||
Yyerror("eof in a macro: %s", s.Name)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
s.Macro = &Macro{
|
||||
Text: base.String(),
|
||||
Narg: n + 1,
|
||||
Dots: dots != 0,
|
||||
}
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#define %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
return
|
||||
|
||||
bad:
|
||||
if s == nil {
|
||||
Yyerror("syntax in #define")
|
||||
} else {
|
||||
Yyerror("syntax in #define: %s", s.Name)
|
||||
}
|
||||
macend()
|
||||
}
|
||||
|
||||
func macexpand(s *Sym) []byte {
|
||||
if s.Macro.Narg == 0 {
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
return []byte(s.Macro.Text)
|
||||
}
|
||||
|
||||
nargs := s.Macro.Narg - 1
|
||||
dots := s.Macro.Dots
|
||||
|
||||
c := getnsc()
|
||||
var arg []string
|
||||
var cp string
|
||||
var out bytes.Buffer
|
||||
if c != '(' {
|
||||
goto bad
|
||||
}
|
||||
c = getc()
|
||||
if c != ')' {
|
||||
unget(c)
|
||||
l := 0
|
||||
var buf bytes.Buffer
|
||||
var c int
|
||||
for {
|
||||
c = getc()
|
||||
if c == '"' {
|
||||
for {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if c == '\\' {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
if c == '"' {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c == '\'' {
|
||||
for {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if c == '\\' {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
if c == '\'' {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c == '/' {
|
||||
c = getc()
|
||||
switch c {
|
||||
case '*':
|
||||
for {
|
||||
c = getc()
|
||||
if c == '*' {
|
||||
c = getc()
|
||||
if c == '/' {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteByte(' ')
|
||||
continue
|
||||
|
||||
case '/':
|
||||
for {
|
||||
c = getc()
|
||||
if !(c != '\n') {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
unget(c)
|
||||
c = '/'
|
||||
}
|
||||
}
|
||||
|
||||
if l == 0 {
|
||||
if c == ',' {
|
||||
if len(arg) == nargs-1 && dots {
|
||||
buf.WriteByte(',')
|
||||
continue
|
||||
}
|
||||
|
||||
arg = append(arg, buf.String())
|
||||
buf.Reset()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == ')' {
|
||||
arg = append(arg, buf.String())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
buf.WriteByte(byte(c))
|
||||
if c == '(' {
|
||||
l++
|
||||
}
|
||||
if c == ')' {
|
||||
l--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(arg) != nargs {
|
||||
Yyerror("argument mismatch expanding: %s", s.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
cp = s.Macro.Text
|
||||
for i := 0; i < len(cp); i++ {
|
||||
c = int(cp[i])
|
||||
if c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
if c != '#' {
|
||||
out.WriteByte(byte(c))
|
||||
continue
|
||||
}
|
||||
|
||||
i++
|
||||
if i >= len(cp) {
|
||||
goto bad
|
||||
}
|
||||
c = int(cp[i])
|
||||
if c == '#' {
|
||||
out.WriteByte(byte(c))
|
||||
continue
|
||||
}
|
||||
|
||||
c -= 'a'
|
||||
if c < 0 || c >= len(arg) {
|
||||
continue
|
||||
}
|
||||
out.WriteString(arg[c])
|
||||
}
|
||||
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, out.String())
|
||||
}
|
||||
return out.Bytes()
|
||||
|
||||
bad:
|
||||
Yyerror("syntax in macro expansion: %s", s.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func macinc() {
|
||||
var c int
|
||||
var buf bytes.Buffer
|
||||
var f *os.File
|
||||
var hp string
|
||||
var str string
|
||||
var symb string
|
||||
|
||||
c0 := getnsc()
|
||||
if c0 != '"' {
|
||||
c = c0
|
||||
if c0 != '<' {
|
||||
goto bad
|
||||
}
|
||||
c0 = '>'
|
||||
}
|
||||
|
||||
for {
|
||||
c = getc()
|
||||
if c == c0 {
|
||||
break
|
||||
}
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
str = buf.String()
|
||||
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
}
|
||||
|
||||
for i := 0; i < len(include); i++ {
|
||||
if i == 0 && c0 == '>' {
|
||||
continue
|
||||
}
|
||||
symb = include[i]
|
||||
symb += "/"
|
||||
if symb == "./" {
|
||||
symb = ""
|
||||
}
|
||||
symb += str
|
||||
var err error
|
||||
f, err = os.Open(symb)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if f == nil {
|
||||
symb = str
|
||||
}
|
||||
hp = symb
|
||||
newio()
|
||||
pushio()
|
||||
newfile(hp, f)
|
||||
return
|
||||
|
||||
bad:
|
||||
unget(c)
|
||||
Yyerror("syntax in #include")
|
||||
macend()
|
||||
}
|
||||
|
||||
func maclin() {
|
||||
var buf bytes.Buffer
|
||||
var symb string
|
||||
|
||||
n := getnsn()
|
||||
c := getc()
|
||||
if n < 0 {
|
||||
goto bad
|
||||
}
|
||||
for {
|
||||
if c == ' ' || c == '\t' {
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == '"' {
|
||||
break
|
||||
}
|
||||
if c == '\n' {
|
||||
symb = "<noname>"
|
||||
goto nn
|
||||
}
|
||||
|
||||
goto bad
|
||||
}
|
||||
|
||||
for {
|
||||
c = getc()
|
||||
if c == '"' {
|
||||
break
|
||||
}
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
symb = buf.String()
|
||||
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
}
|
||||
|
||||
nn:
|
||||
Ctxt.LineHist.Update(int(Lineno), symb, int(n))
|
||||
return
|
||||
|
||||
bad:
|
||||
unget(c)
|
||||
Yyerror("syntax in #line")
|
||||
macend()
|
||||
}
|
||||
|
||||
func macif(f int) {
|
||||
var c int
|
||||
var l int
|
||||
var bol int
|
||||
var s *Sym
|
||||
|
||||
if f == 2 {
|
||||
goto skip
|
||||
}
|
||||
s = getsym()
|
||||
if s == nil {
|
||||
goto bad
|
||||
}
|
||||
if getcom() != '\n' {
|
||||
goto bad
|
||||
}
|
||||
if (s.Macro != nil) != (f != 0) {
|
||||
return
|
||||
}
|
||||
|
||||
skip:
|
||||
bol = 1
|
||||
l = 0
|
||||
for {
|
||||
c = getc()
|
||||
if c != '#' {
|
||||
if !isspace(c) {
|
||||
bol = 0
|
||||
}
|
||||
if c == '\n' {
|
||||
bol = 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if !(bol != 0) {
|
||||
continue
|
||||
}
|
||||
s = getsym()
|
||||
if s == nil {
|
||||
continue
|
||||
}
|
||||
if s.Name == "endif" {
|
||||
if l != 0 {
|
||||
l--
|
||||
continue
|
||||
}
|
||||
|
||||
macend()
|
||||
return
|
||||
}
|
||||
|
||||
if s.Name == "ifdef" || s.Name == "ifndef" {
|
||||
l++
|
||||
continue
|
||||
}
|
||||
|
||||
if l == 0 && f != 2 && s.Name == "else" {
|
||||
macend()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
bad:
|
||||
Yyerror("syntax in #if(n)def")
|
||||
macend()
|
||||
}
|
||||
|
||||
func macprag() {
|
||||
var c int
|
||||
|
||||
s := getsym()
|
||||
|
||||
if s != nil && s.Name == "lib" {
|
||||
c0 := getnsc()
|
||||
if c0 != '"' {
|
||||
c = c0
|
||||
if c0 != '<' {
|
||||
goto bad
|
||||
}
|
||||
c0 = '>'
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
for {
|
||||
c = getc()
|
||||
if c == c0 {
|
||||
break
|
||||
}
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
symb := buf.String()
|
||||
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
}
|
||||
|
||||
/*
|
||||
* put pragma-line in as a funny history
|
||||
*/
|
||||
Ctxt.AddImport(symb)
|
||||
return
|
||||
}
|
||||
if s != nil && s.Name == "pack" {
|
||||
pragpack()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && s.Name == "fpround" {
|
||||
pragfpround()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && s.Name == "textflag" {
|
||||
pragtextflag()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && s.Name == "dataflag" {
|
||||
pragdataflag()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && s.Name == "varargck" {
|
||||
pragvararg()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && s.Name == "incomplete" {
|
||||
pragincomplete()
|
||||
return
|
||||
}
|
||||
|
||||
if s != nil && (strings.HasPrefix(s.Name, "cgo_") || strings.HasPrefix(s.Name, "dyn")) {
|
||||
pragcgo(s.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for getnsc() != '\n' {
|
||||
}
|
||||
return
|
||||
|
||||
bad:
|
||||
unget(c)
|
||||
Yyerror("syntax in #pragma lib")
|
||||
macend()
|
||||
}
|
||||
|
||||
func macend() {
|
||||
var c int
|
||||
|
||||
for {
|
||||
c = getnsc()
|
||||
if c < 0 || c == '\n' {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user