From 861af80458e846bc535f262cca23649e703b7885 Mon Sep 17 00:00:00 2001 From: Mikio Hara Date: Wed, 29 Jul 2015 12:55:19 +0900 Subject: [PATCH] cmd/internal/asm: delete Updates #10510. Change-Id: Ib4d39943969d18517b373292b83d87650d5df12a Reviewed-on: https://go-review.googlesource.com/12787 Run-TryBot: Mikio Hara TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/internal/asm/asm.go | 307 ------------ src/cmd/internal/asm/lexbody.go | 710 -------------------------- src/cmd/internal/asm/macbody.go | 855 -------------------------------- 3 files changed, 1872 deletions(-) delete mode 100644 src/cmd/internal/asm/asm.go delete mode 100644 src/cmd/internal/asm/lexbody.go delete mode 100644 src/cmd/internal/asm/macbody.go diff --git a/src/cmd/internal/asm/asm.go b/src/cmd/internal/asm/asm.go deleted file mode 100644 index b96c2cbb2a..0000000000 --- a/src/cmd/internal/asm/asm.go +++ /dev/null @@ -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 "" -} - -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 -} diff --git a/src/cmd/internal/asm/lexbody.go b/src/cmd/internal/asm/lexbody.go deleted file mode 100644 index a1519c8566..0000000000 --- a/src/cmd/internal/asm/lexbody.go +++ /dev/null @@ -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 -} diff --git a/src/cmd/internal/asm/macbody.go b/src/cmd/internal/asm/macbody.go deleted file mode 100644 index 4565d3a37f..0000000000 --- a/src/cmd/internal/asm/macbody.go +++ /dev/null @@ -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 = "" - 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 - } - } -} -- 2.50.0