Example #1
0
func test(t *testing.T, src string, code []cpu.Word) {
	var ast parser.AST

	files, err := path.SourceFiles(src)
	if err != nil {
		t.Fatal(err)
	}

	for i := range files {
		err = ast.Parse(files[i], 0)
		if err != nil {
			t.Fatal(err)
		}
	}

	ar, err := Assemble(&ast, 0)
	if err != nil {
		t.Fatal(err)
	}

	if len(code) != len(ar.Code) {
		t.Fatalf("Code size mismatch. Expected %d, have %d\n%04x\n%04x",
			len(code), len(ar.Code), code, ar.Code)
	}

	for i := range code {
		if code[i] != cpu.Word(ar.Code[i]) {
			t.Fatalf("Code mismatch at instruction %d:\nWant: %04x\nHave: %04x", i, code, ar.Code)
		}
	}
}
Example #2
0
// findDeps creates a tree of dependencies (import paths) for
// the given package. It parses the package source code for this purpose.
func findDeps(importpath string, list *[]string) bool {
	if containsDep(*list, importpath) {
		return true
	}

	// Find source files for the given package.
	sources, err := path.SourceFiles(importpath)
	if err != nil {
		return false
	}

	// Parse sources into a partial AST.
	// We are only interested in the import statements.
	var ast parser.AST
	for _, file := range sources {
		err = ast.Parse(file, parser.ImportsOnly)

		if err != nil {
			return false
		}
	}

	// Create a new dependency entry.
	*list = append(*list, importpath)

	for _, imp := range ast.Imports {
		if !findDeps(imp.Path.Value, list) {
			return false
		}
	}

	return true
}
Example #3
0
func doTest(t *testing.T, src string, sbin ...cpu.Word) {
	var ast parser.AST
	var dbin []cpu.Word

	buf := bytes.NewBufferString(src)
	err := ast.Parse(buf, "")

	if err != nil {
		t.Fatal(err)
	}

	dbin, _, err = Assemble(&ast)
	if err != nil {
		t.Fatal(err)
	}

	if len(dbin) != len(sbin) {
		fmt.Printf("%04x\n", dbin)
		fmt.Printf("%04x\n", sbin)
		t.Fatalf("Size mismatch. Expect %d, got %d", len(sbin), len(dbin))
	}

	for i := range sbin {
		if dbin[i] != sbin[i] {
			fmt.Printf("%04x\n", dbin)
			fmt.Printf("%04x\n", sbin)
			t.Fatalf("Code mismatch at %d. Expect %04x, got %04x", i, sbin[i], dbin[i])
		}
	}
}
Example #4
0
// readSource reads the given file and parses its contents
// into the given AST.
func readSource(ast *parser.AST, file string) error {
	fd, err := os.Open(file)
	if err != nil {
		return err
	}

	defer fd.Close()
	return ast.Parse(fd, file)
}
Example #5
0
File: funcs.go Project: DanB91/dcpu
// parseFunctions resolves function constants and it injects the
// necessary function prolog and epilog code.
//
// What the latter means, is that we analyze the registers being
// used. If any of them are registers that are guaranteed to
// be preserved across function calls, then we explicitly inject stack
// push/pop instructions to save their state.
//
// If there are any `return` instructions, we replace them with `set pc, $$`.
// Where `$$` is a label we generate which points to the function epilog.
func parseFunctions(ast *parser.AST) (err error) {
	list := ast.Functions()

	for i := range list {
		if err = parseFuncConst(ast, list[i]); err != nil {
			return
		}

		fixFunctionReturns(ast, list[i])
		injectFunctionCode(ast, list[i])
	}

	return
}
Example #6
0
func Format(in, out string) (err error) {
	var fout io.WriteCloser
	var fin io.ReadCloser
	var ast parser.AST

	// Open input stream.
	if in == Stdin {
		fin = _stdin
	} else {
		fin, err = os.Open(in)
		if err != nil {
			return
		}
	}

	// Parse source into AST.
	err = ast.Parse(fin, in)
	fin.Close()

	if err != nil {
		return
	}

	if *strip {
		StripComments(&ast)
	}

	// Open output stream.
	if out == Stdout {
		fout = _stdout
	} else {
		fout, err = os.Create(out)
		if err != nil {
			return
		}

		defer fout.Close()
	}

	// Write source.
	sw := util.NewSourceWriter(fout, &ast)
	sw.Tabs = *tabs
	sw.TabWidth = *tabwidth
	sw.Comments = !*strip
	sw.Write()
	return
}
Example #7
0
// build builds the given package and its dependencies.
func build(importpath string, flags asm.AsmFlags) (err error) {
	files, _ := path.SourceFiles(importpath)
	if len(files) == 0 {
		return nil // No source files
	}

	var ast parser.AST
	for i := range files {
		err = ast.Parse(files[i], 0)
		if err != nil {
			return
		}
	}

	ar, err := asm.Assemble(&ast, flags)
	if err != nil {
		return
	}

	return writeArchive(ar, importpath)
}