Example #1
0
func declareFile(b *builder, pkg *pkg, file *file) {
	// declare functions
	for _, fn := range file.funcs {
		t := fn.Name
		sym := sym8.Make(b.path, t.Lit, SymFunc, fn, nil, t.Pos)
		if !declareSymbol(b, sym) {
			continue
		}

		b.curPkg.declare(sym)
		// b.index(t.Lit, b.curPkg.Declare(sym))
	}

	// declare variables
	for _, v := range file.vars {
		t := v.Name
		sym := sym8.Make(b.path, t.Lit, SymVar, v, nil, t.Pos)
		if !declareSymbol(b, sym) {
			continue
		}

		b.curPkg.declare(sym)
		// b.index(t.Lit, b.curPkg.Declare(sym))
	}
}
Example #2
0
func buildFields(b *builder, ps *pkgStruct) {
	s := ps.ast
	t := ps.t

	for _, f := range s.Fields {
		ft := b.buildType(f.Type)
		if ft == nil {
			continue
		}

		for _, id := range f.Idents.Idents {
			name := id.Lit
			field := &types.Field{Name: name, T: ft}
			sym := sym8.Make(b.path, name, tast.SymField, field, ft, id.Pos)
			conflict := t.Syms.Declare(sym)
			if conflict != nil {
				b.Errorf(id.Pos, "field %s already defined", id.Lit)
				b.Errorf(conflict.Pos, "previously defined here")
				continue
			}

			t.AddField(field)
		}
	}
}
Example #3
0
func declareVar(b *builder, tok *lex8.Token, t types.T) *sym8.Symbol {
	name := tok.Lit
	s := sym8.Make(b.path, name, tast.SymVar, nil, t, tok.Pos)
	conflict := b.scope.Declare(s)
	if conflict != nil {
		b.Errorf(tok.Pos, "%q already defined as a %s",
			name, tast.SymStr(conflict.Type),
		)
		b.Errorf(conflict.Pos, "previously defined here")
		return nil
	}
	return s
}
Example #4
0
func declareFuncSym(b *builder, f *ast.Func, t types.T) *sym8.Symbol {
	name := f.Name.Lit
	s := sym8.Make(b.path, name, tast.SymFunc, nil, t, f.Name.Pos)
	conflict := b.scope.Declare(s)
	if conflict != nil {
		b.Errorf(f.Name.Pos, "%q already defined as a %s",
			name, tast.SymStr(conflict.Type),
		)
		b.Errorf(conflict.Pos, "previously defined here")
		return nil
	}
	return s
}
Example #5
0
// declareLabels adds the labels into the scope,
// so that later they can be queried for filling.
func declareLabels(b *builder, f *funcDecl) {
	for _, stmt := range f.stmts {
		if !stmt.isLabel() {
			continue
		}

		lab := stmt.label
		op := stmt.Ops[0]
		sym := sym8.Make(b.path, lab, SymLabel, stmt, nil, op.Pos)
		decl := b.scope.Declare(sym)
		if decl != nil {
			b.Errorf(op.Pos, "%q already declared", lab)
			b.Errorf(decl.Pos, "  here as a %s", SymStr(decl.Type))
			continue
		}
	}
}
Example #6
0
func buildPkgScope(b *builder, pkg *pkg) {
	if pkg.imports != nil {
		for as, stmt := range pkg.imports.stmts {
			sym := sym8.Make(b.path, as, SymImport, stmt, nil, stmt.Path.Pos)
			if !declareSymbol(b, sym) {
				continue
			}

			b.importPkg(stmt.path, as)
			// b.index(as, b.curPkg.Require(stmt.lib))
		}
	}

	for _, file := range pkg.files {
		declareFile(b, pkg, file)
	}
}
Example #7
0
func declareStruct(b *builder, s *ast.Struct) *pkgStruct {
	ret := newPkgStruct(s)
	name := ret.name.Lit
	pos := ret.name.Pos
	t := &types.Type{ret.t}
	sym := sym8.Make(b.path, name, tast.SymStruct, nil, t, pos)
	conflict := b.scope.Declare(sym)
	if conflict != nil {
		b.Errorf(pos, "%s already defined", name)
		b.Errorf(conflict.Pos, "previously defined here as a %s",
			tast.SymStr(conflict.Type),
		)
		return nil
	}

	ret.sym = sym
	return ret
}
Example #8
0
func buildImports(
	b *builder, f *ast.File, imps map[string]*build8.Package,
) []*sym8.Symbol {
	if f.Imports == nil {
		return nil
	}

	var ret []*sym8.Symbol
	for _, d := range f.Imports.Decls {
		_, as, e := ast.ImportPathAs(d)
		if e != nil {
			b.Errorf(d.Path.Pos, "invalid import path")
			continue
		}

		p := imps[as]
		if p == nil {
			b.Errorf(d.Path.Pos, "package %s missing", as)
			continue
		}

		pos := ast.ImportPos(d)
		if !(p.Lang == "asm8" || p.Lang == "g8") {
			b.Errorf(pos, "cannot import %q pacakge %q",
				p.Lang, as,
			)
			continue
		}

		t := &types.Pkg{as, p.Lang, p.Symbols}
		sym := sym8.Make(b.path, as, tast.SymImport, nil, t, pos)
		conflict := b.scope.Declare(sym)
		if conflict != nil {
			b.Errorf(pos, "%s already imported", as)
			continue
		}

		ret = append(ret, sym)
	}
	return ret
}
Example #9
0
func declareMethod(b *builder, ps *pkgStruct, f *ast.Func) *pkgFunc {
	if f.Alias != nil {
		b.Errorf(f.Alias.Eq.Pos, "cannot alias a function for a method")
		return nil
	}

	t := buildFuncType(b, ps.pt, f.FuncSig)
	if t == nil {
		return nil
	}

	name := f.Name.Lit
	sym := sym8.Make(b.path, name, tast.SymFunc, nil, t, f.Name.Pos)
	conflict := ps.t.Syms.Declare(sym)
	if conflict != nil {
		b.Errorf(f.Name.Pos, "member %s already defined", name)
		b.Errorf(conflict.Pos, "previously defined here")
		return nil
	}

	return &pkgFunc{sym: sym, f: f, recv: ps}
}
Example #10
0
func declareBuiltin(b *builder, builtin *link8.Pkg) {
	path := builtin.Path()
	e := b.p.HookBuiltin(builtin)
	if e != nil {
		b.Errorf(nil, e.Error())
		return
	}

	o := func(name, as string, t *types.Func) ir.Ref {
		sym := builtin.SymbolByName(name)
		if sym == nil {
			b.Errorf(nil, "builtin symbol %s missing", name)
			return nil
		} else if sym.Type != link8.SymFunc {
			b.Errorf(nil, "builtin symbol %s is not a function", name)
			return nil
		}

		ref := ir.NewFuncSym(path, name, makeFuncSig(t))
		obj := &objFunc{name: as, ref: newRef(t, ref)}
		s := sym8.Make(b.path, as, tast.SymFunc, obj, t, nil)
		pre := b.scope.Declare(s)
		if pre != nil {
			b.Errorf(nil, "builtin symbol %s declare failed", name)
			return nil
		}
		return ref
	}

	// TODO: export these as generic function pointer symbols, and convert
	// them into G functions in g files, rather than inside here in the
	// compiler.
	o("PrintInt32", "printInt", types.NewVoidFunc(types.Int))
	o("PrintUint32", "printUint", types.NewVoidFunc(types.Uint))
	o("PrintChar", "printChar", types.NewVoidFunc(types.Int8))
	b.panicFunc = o("Panic", "panic", types.VoidFunc)

	bi := func(name string) {
		t := types.NewBuiltInFunc(name)
		obj := &objFunc{name: name, ref: newRef(t, nil)}
		s := sym8.Make(b.path, name, tast.SymFunc, obj, t, nil)
		pre := b.scope.Declare(s)
		if pre != nil {
			b.Errorf(nil, "builtin symbol %s declare failed", name)
		}
	}

	bi("len")
	bi("make")

	c := func(name string, r *ref) {
		// TODO: declare these as typed consts
		obj := &objConst{name, r}
		s := sym8.Make(b.path, name, tast.SymConst, obj, r.Type(), nil)
		pre := b.scope.Declare(s)
		if pre != nil {
			b.Errorf(nil, "builtin symbol %s declare failed", name)
		}
	}

	c("true", refTrue)
	c("false", refFalse)
	c("nil", refNil)

	t := func(name string, t types.T) {
		s := sym8.Make(b.path, name, tast.SymType, nil, &types.Type{t}, nil)
		pre := b.scope.Declare(s)
		if pre != nil {
			b.Errorf(nil, "builtin symbol %s declare failed", name)
		}
	}

	t("int", types.Int)
	t("uint", types.Uint)
	t("int32", types.Int)
	t("uint32", types.Uint)
	t("int8", types.Int8)
	t("uint8", types.Uint8)
	t("char", types.Int8)
	t("byte", types.Uint8)
	t("bool", types.Bool)
	t("float", types.Float32)
	t("string", types.String)
	// t("ptr", &types.Pointer{types.Uint8})
	// t("float32", types.Float32)
	// t("string", types.String)
}