Esempio n. 1
0
// CompileDir generates C source code for the Calc sources found in the
// directory specified by path. The C source file uses the same name as
// directory rather than any individual file.
func CompileDir(path string, opt bool) error {
	fset := token.NewFileSet()
	p, err := parse.ParseDir(fset, path)
	if err != nil {
		return err
	}

	pkg := ir.MakePackage(p, filepath.Base(path))
	if err := ir.TypeCheck(pkg, fset); err != nil {
		return err
	}
	if opt {
		pkg = ir.FoldConstants(pkg).(*ir.Package)
	}
	//ir.Tag(pkg)

	fp, err := os.Create(filepath.Join(path, filepath.Base(path)) + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c := &compiler{fp: fp, fset: fset}

	c.emitHeaders()
	c.compPackage(pkg)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}
Esempio n. 2
0
func TestAssignmentFolding(t *testing.T) {
	test := FoldTest{src: "(= a (* 1 1))", expect: "1"}
	name := "assign"
	expr, _ := parse.ParseExpression(name, test.src)
	o := ir.FoldConstants(ir.MakeExpr(ir.MakePackage(&ast.Package{}, name), expr))
	validate_constant(t, name, o.(*ir.Assignment).Rhs, test)
}
Esempio n. 3
0
func TestCallFolding(t *testing.T) {
	src := "(fn (== 3 2) (+ 2 2))"
	name := "call"
	expr, _ := parse.ParseExpression(name, src)
	o := ir.FoldConstants(ir.MakeExpr(ir.MakePackage(&ast.Package{}, name), expr))
	validate_constant(t, name, o.(*ir.Call).Args[0], FoldTest{src, "false"})
	validate_constant(t, name, o.(*ir.Call).Args[1], FoldTest{src, "4"})
}
Esempio n. 4
0
func TestVarFolding(t *testing.T) {
	test := FoldTest{src: "(var (a:int):int (= a (/ 24 3)))", expect: "8"}
	name := "var"
	expr, _ := parse.ParseExpression(name, test.src)
	o := ir.FoldConstants(ir.MakeExpr(ir.MakePackage(&ast.Package{}, name), expr))
	o = o.(*ir.Variable).Body[0].(*ir.Assignment).Rhs
	validate_constant(t, name, o, test)
}
Esempio n. 5
0
func TestIfFolding(t *testing.T) {
	src := "(if (== false (!= 3 3)):int (/ 9 3) (* 1 2 3))"
	name := "if"
	expr, _ := parse.ParseExpression(name, src)
	o := ir.FoldConstants(ir.MakeExpr(ir.MakePackage(&ast.Package{}, name), expr))
	validate_constant(t, name, o.(*ir.If).Cond, FoldTest{src, "true"})
	validate_constant(t, name, o.(*ir.If).Then, FoldTest{src, "3"})
	validate_constant(t, name, o.(*ir.If).Else, FoldTest{src, "6"})
}
Esempio n. 6
0
func TestPackageFolding(t *testing.T) {
	fs := token.NewFileSet()
	f1, _ := parse.ParseFile(fs, "package", "(define f1 (func:int (+ 1 2)))")
	f2, _ := parse.ParseFile(fs, "package", "(define f2 (func:int (* 8 2)))")
	pkg := &ast.Package{Files: []*ast.File{f1, f2}}
	o := ir.FoldConstants(ir.MakePackage(pkg, "package"))
	o1 := o.(*ir.Package).Scope().Lookup("f1")
	o2 := o.(*ir.Package).Scope().Lookup("f2")
	validate_constant(t, "package", o1.(*ir.Define).Body.(*ir.Function).Body[0],
		FoldTest{"", "3"})
	validate_constant(t, "package", o2.(*ir.Define).Body.(*ir.Function).Body[0],
		FoldTest{"", "16"})
}
Esempio n. 7
0
// CompileFile generates a C source file for the corresponding file
// specified by path. The .calc extension for the filename in path is
// replaced with .c for the C source output.
func CompileFile(path string, opt bool) error {
	fset := token.NewFileSet()
	f, err := parse.ParseFile(fset, path, "")
	if err != nil {
		return err
	}

	pkg := ir.MakePackage(&ast.Package{
		Files: []*ast.File{f},
	}, filepath.Base(path))

	if err := ir.TypeCheck(pkg, fset); err != nil {
		return err
	}
	if opt {
		pkg = ir.FoldConstants(pkg).(*ir.Package)
	}
	//ir.Tag(pkg)

	path = path[:len(path)-len(filepath.Ext(path))]
	fp, err := os.Create(path + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c := &compiler{fp: fp}

	c.emitHeaders()
	c.compPackage(pkg)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}
Esempio n. 8
0
func test_folding(t *testing.T, name string, test FoldTest) {
	expr, _ := parse.ParseExpression(name, test.src)
	o := ir.FoldConstants(ir.MakeExpr(ir.MakePackage(&ast.Package{}, name), expr))
	validate_constant(t, name, o, test)
}