1 // Inferno utils/cc/lexbody
2 // http://code.google.com/p/inferno-os/source/browse/utils/cc/lexbody
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6 // Portions Copyright © 1997-1999 Vita Nuova Limited
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8 // Portions Copyright © 2004,2006 Bruce Ellis
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11 // Portions Copyright © 2009 The Go Authors. All rights reserved.
13 // Permission is hereby granted, free of charge, to any person obtaining a copy
14 // of this software and associated documentation files (the "Software"), to deal
15 // in the Software without restriction, including without limitation the rights
16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 // copies of the Software, and to permit persons to whom the Software is
18 // furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included in
21 // all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34 * common code for all the assemblers
38 for getnsc() != '\n' {
44 for getnsc() != '\n' {
49 func pragcgo(name string) {
50 for getnsc() != '\n' {
56 for getnsc() != '\n' {
62 for getnsc() != '\n' {
68 for getnsc() != '\n' {
74 for getnsc() != '\n' {
79 func pragincomplete() {
80 for getnsc() != '\n' {
85 func Alloc(n int32) interface{} {
90 fmt.Printf("alloc out of mem\n")
91 main.Exits("alloc: out of mem")
98 func Allocn(p interface{}, n int32, d int32) interface{} {
102 p = main.Realloc(p, int(n+d))
104 fmt.Printf("allocn out of mem\n")
105 main.Exits("allocn: out of mem")
109 main.Memset(p.(string)[n:], 0, d)
114 func Ensuresymb(n int32) {
115 if new5a.Symb == nil {
116 new5a.Symb = Alloc(new5a.NSYMB + 1).(string)
117 new5a.Nsymb = new5a.NSYMB
121 new5a.Symb = Allocn(new5a.Symb, new5a.Nsymb, n+1-new5a.Nsymb).(string)
126 func Setinclude(p string) {
132 for i = 1; i < new5a.Ninclude; i++ {
133 if p == new5a.Include[i] {
138 if new5a.Ninclude%8 == 0 {
139 new5a.Include = Allocn(new5a.Include, new5a.Ninclude*sizeof(string), 8*sizeof(string)).(*string)
141 new5a.Include[new5a.Ninclude] = p
146 obj.Bflush(&new5a.Bstdout)
147 if new5a.Outfile != "" {
148 main.Remove(new5a.Outfile)
158 Yyerror("botch in pushio")
163 i.C = int16(new5a.Fi.c)
168 var pushdepth int = 0
173 if pushdepth > 1000 {
174 Yyerror("macro/io expansion too deep")
178 i = Alloc(sizeof(*i)).(*new5a.Io)
181 new5a.Iofree = i.Link
188 func newfile(s string, f int) {
192 i.Link = new5a.Iostack
196 i.F = int16(main.Open(s, 0))
199 Yyerror("%ca: %r: %s", new5a.Thechar, s)
204 obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), s, 0)
207 func Slookup(s string) *new5a.Sym {
208 Ensuresymb(int32(len(s)))
213 var thetext *obj.LSym
215 func settext(s *obj.LSym) {
219 func labellookup(s *new5a.Sym) *new5a.Sym {
228 p = string(fmt.Sprintf("%s.%s", thetext.Name, s.Name))
231 lab.Labelname = s.Name
235 func lookup() *new5a.Sym {
244 if uint8(new5a.Symb[0]) == 0xc2 && uint8(new5a.Symb[1]) == 0xb7 {
245 // turn leading · into ""·
246 h = uint32(len(new5a.Symb))
248 Ensuresymb(int32(h + 2))
249 main.Memmove(new5a.Symb[2:], new5a.Symb, h+1)
255 for r = w; r[0] != 0; r = r[1:] {
256 // turn · (U+00B7) into .
257 // turn ∕ (U+2215) into /
258 if uint8(r[0]) == 0xc2 && uint8((r[1:])[0]) == 0xb7 {
263 } else if uint8(r[0]) == 0xe2 && uint8((r[1:])[0]) == 0x88 && uint8((r[2:])[0]) == 0x95 {
278 for p = new5a.Symb; ; p = p[1:] {
283 h = h + h + h + uint32(c)
285 l = (-cap(p) + cap(new5a.Symb)) + 1
288 c = int(new5a.Symb[0])
289 for s = new5a.Hash[h]; s != nil; s = s.Link {
290 if int(s.Name[0]) != c {
293 if s.Name == new5a.Symb {
298 s = Alloc(sizeof(*s)).(*new5a.Sym)
299 s.Name = Alloc(int32(l)).(string)
300 main.Memmove(s.Name, new5a.Symb, l)
302 s.Link = new5a.Hash[h]
308 func ISALPHA(c int) int {
309 if main.Isalpha(c) != 0 {
312 if c >= main.Runeself {
326 new5a.Peekc = new5a.IGN
335 new5a.Peekc = new5a.EOF
339 if main.Isspace(c) != 0 {
351 if main.Isdigit(c) != 0 {
372 if main.Isdigit(c) != 0 {
391 if ISALPHA(c) != 0 || main.Isdigit(c) != 0 || c == '_' || c == '$' {
402 new5a.Ionext.Link = new5a.Iostack
403 new5a.Iostack = new5a.Ionext
406 if new5a.Peekc != new5a.IGN {
407 cp[new5a.Fi.c] = byte(new5a.Peekc)
410 new5a.Peekc = new5a.IGN
417 s.Type_ = new5a.LNAME
419 if s.Type_ == new5a.LNAME || s.Type_ == new5a.LVAR || s.Type_ == new5a.LLAB {
421 return int32(s.Type_)
424 new5a.Yylval.lval = s.Value
425 return int32(s.Type_)
436 if c == 'x' || c == 'X' {
439 } else if c < '0' || c > '7' {
442 new5a.Yylval.lval = 0
444 if c >= '0' && c <= '9' {
445 if c > '7' && c1 == 3 {
448 new5a.Yylval.lval = int32(uint64(new5a.Yylval.lval) << uint(c1))
449 new5a.Yylval.lval += int32(c) - '0'
457 if c >= 'A' && c <= 'F' {
460 if c >= 'a' && c <= 'f' {
461 new5a.Yylval.lval = int32(uint64(new5a.Yylval.lval) << uint(c1))
462 new5a.Yylval.lval += int32(c) - 'a' + 10
474 if !(main.Isdigit(c) != 0) {
485 if c == 'e' || c == 'E' {
489 if sizeof(new5a.Yylval.lval) == sizeof(int64) {
490 new5a.Yylval.lval = int32(main.Strtoll(new5a.Symb, nil, 10))
493 new5a.Yylval.lval = int32(main.Strtol(new5a.Symb, nil, 10))
497 for c == 'U' || c == 'u' || c == 'l' || c == 'L' {
508 if !(main.Isdigit(c) != 0) {
513 if c == 'e' || c == 'E' {
522 if c == '+' || c == '-' {
528 for main.Isdigit(c) != 0 {
537 if new5a.FPCHIP != 0 /*TypeKind(100016)*/ {
538 new5a.Yylval.dval = main.Atof(new5a.Symb)
542 Yyerror("assembler cannot interpret fp constants")
543 new5a.Yylval.lval = 1
547 main.Memmove(new5a.Yylval.sval, new5a.Nullgen.U.Sval, sizeof(new5a.Yylval.sval))
548 cp = new5a.Yylval.sval
555 if c1 < sizeof(new5a.Yylval.sval) {
562 if c1 > sizeof(new5a.Yylval.sval) {
563 Yyerror("string constant too long")
572 if escchar('\'') != new5a.EOF {
575 new5a.Yylval.lval = int32(c)
587 Yyerror("eof in comment")
604 Yyerror("eof in comment")
627 new5a.Peekc = new5a.IGN
636 Yyerror("End of file")
648 if !(main.Isspace(c) != 0) || c == '\n' {
661 func escchar(e int) int {
668 Yyerror("newline in string")
680 if c >= '0' && c <= '7' {
683 if c >= '0' && c <= '7' {
686 if c >= '0' && c <= '7' {
720 func Pinit(f string) {
728 new5a.Peekc = new5a.IGN
730 for i = 0; i < new5a.NHASH; i++ {
731 for s = new5a.Hash[i]; s != nil; s = s.Link {
748 new5a.Fi.c = main.Read(int(i.F), i.B, new5a.BUFSIZ) - 1
751 obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), "", 0)
756 return int(i.B[0]) & 0xff
759 new5a.Iostack = i.Link
760 i.Link = new5a.Iofree
767 new5a.Fi.c = int(i.C)
773 new5a.Fi.p = new5a.Fi.p[1:]
774 return int(tmp8[0]) & 0xff
777 func Yyerror(a string, args ...interface{}) {
779 var arg []interface{}
782 * hack to intercept message from yaccpar
784 if a == "syntax error" {
786 Yyerror("syntax error, last name: %s", new5a.Symb)
791 main.Va_start(arg, a)
792 obj.Vseprint(buf, buf[sizeof(buf):], a, arg)
794 fmt.Printf("%s\n", buf)
796 if new5a.Nerrors > 10 {
797 fmt.Printf("too many errors\n")
802 func prfile(l int32) {
803 obj.Linkprfile(new5a.Ctxt, l)