Beispiel #1
0
func TestParseVar(t *testing.T) {
	types := []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, IDENT}
	src := "(decl main int (var a int))"
	file := token.NewFile("var.calc", 1, len(src))
	f := parse.ParseFile(file, "var.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, IDENT, ASSIGN,
		IDENT, BASIC}
	src = "(decl main int (var (= a 5) int))"
	file = token.NewFile("var2.calc", 1, len(src))
	f = parse.ParseFile(file, "var2.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, VAR, IDENT, ASSIGN, IDENT, BASIC}
	src = "(decl main int (var (= a 5)))"
	file = token.NewFile("var3.calc", 1, len(src))
	f = parse.ParseFile(file, "var3.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #2
0
func TestParseIf(t *testing.T) {
	types := []Type{FILE, DECL, IDENT, IDENT, IF, IDENT, IDENT, BASIC}
	src := "(decl main int (if true int 3))"
	file := token.NewFile("if.calc", 1, len(src))
	f := parse.ParseFile(file, "if.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, IF, BINARY, IDENT, IDENT, IDENT,
		IDENT, LIST, BINARY, IDENT, BASIC, IDENT}
	src = "(decl main int (if (< a b) int a ((+ b 1) b)))"
	file = token.NewFile("if2.calc", 1, len(src))
	f = parse.ParseFile(file, "if2.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, IF, BINARY, IDENT, IDENT, LIST,
		ASSIGN, IDENT, IDENT}
	src = "(decl main int (if (< a b) ((= a b))))"
	file = token.NewFile("if3.calc", 1, len(src))
	f = parse.ParseFile(file, "if3.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #3
0
func TestParseDecl(t *testing.T) {
	types := []Type{FILE, DECL, IDENT, IDENT, IDENT}
	src := "(decl func int a)"
	file := token.NewFile("decl1.calc", 1, len(src))
	f := parse.ParseFile(file, "decl1.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, BINARY, BASIC, BASIC}
	src = "(decl five int (+ 2 3))"
	file = token.NewFile("decl2.calc", 1, len(src))
	f = parse.ParseFile(file, "decl1.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, IDENT, IDENT, BINARY,
		IDENT, IDENT}
	src = "(decl add(a b int) int (+ a b))"
	file = token.NewFile("decl3.calc", 1, len(src))
	f = parse.ParseFile(file, "decl2.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #4
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"})
}
Beispiel #5
0
func TestExpectFail(t *testing.T) {
	var tests = []string{
		"+ 3 5)",
		"(- 5)",
		"(3 5 +)",
		"(3 + 4)",
		"(+ 6 2",
		"(- 4 5)2",
		"(d",
		"(% / d)",
		"(& 3 5)",
		"((+ 3 5) 5)",
		"(* (- 2 6) (+ 4 2)())",
		";comment",
		"(var a)",
		"(decl main () int a)",
		"(decl main int ())",
		"(decl main int a)(decl main in b)",
		"(var a)",
		"(var (+ a b))",
		"(var 23)",
		"(var a int)(var a int)",
	}
	for _, src := range tests {
		file := token.NewFile("expectfail", 1, len(src))
		if f := parse.ParseFile(file, "expectfail", src); f != nil {
			t.Log(src, "- not nil")
			t.Fail()
		}
	}
}
Beispiel #6
0
func CompileFile(path string) {
	var c compiler

	c.fset = token.NewFileSet()
	f := parse.ParseFile(c.fset, path)
	if f == nil {
		os.Exit(1)
	}

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

	c.fp = fp
	c.compFile(f)

	if c.errors.Count() != 0 {
		c.errors.Print()
		os.Exit(1)
	}
}
Beispiel #7
0
func test_file(t *testing.T, name string, test Test) {
	f, err := parse.ParseFile(token.NewFileSet(), name, test.src)
	if err != nil {
		t.Fatal(err)
	}
	test_handler(t, test, name, &ast.Package{Files: []*ast.File{f}})
}
Beispiel #8
0
func TestParseFileBasic(t *testing.T) {
	types := []Type{FILE, DECL, IDENT, IDENT, BINARY, BASIC, BASIC}
	src := "(decl main int (+ 1 2))"
	file := token.NewFile("basicdec", 1, len(src))
	f := parse.ParseFile(file, "basicdec", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #9
0
func TestParseNested(t *testing.T) {
	var types = []Type{FILE, DECL, IDENT, IDENT, BINARY, BINARY, BASIC, BASIC,
		BASIC, BINARY, BASIC, BASIC}
	src := ";comment\n(decl main int (+ (/ 9 3) 5 (- 3 1)))"
	file := token.NewFile("nested.calc", 1, len(src))
	f := parse.ParseFile(file, "nested.calc", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #10
0
func TestParseCall(t *testing.T) {
	types := []Type{FILE, DECL, IDENT, IDENT, CALL, IDENT, BASIC, BASIC,
		BASIC, BASIC}
	src := "(decl main int (add 1 2 3 4))"
	file := token.NewFile("call1", 1, len(src))
	f := parse.ParseFile(file, "call1", "(decl main int (add 1 2 3 4))")
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))

	types = []Type{FILE, DECL, IDENT, IDENT, CALL, IDENT}
	src = "(decl main int (nothing))"
	file = token.NewFile("call1", 1, len(src))
	f = parse.ParseFile(file, "call1", src)
	if f == nil {
		t.Fatal("Failed to parse")
	}
	ast.Walk(f, nodeTest(types, t))
}
Beispiel #11
0
func TestParseFile(t *testing.T) {
	test := Test{"bad-ext", "", []Type{}, false}

	// test for file with bad extension
	f, err := ioutil.TempFile("", "")
	if err != nil {
		t.Log(err)
	}
	defer func() {
		f.Close()
		err := os.Remove(f.Name())
		t.Log(err)
	}()
	n, err := parse.ParseFile(token.NewFileSet(), f.Name(), "")
	checkTest(t, test, n, err)

	test = Test{"simple.calc", "(define main (func:int 0))",
		[]Type{FILE, DEFINE, FUNC, BASIC},
		true}
	f, err = os.Create(test.name)
	if err != nil {
		t.Log(err)
	}
	defer func() {
		f.Close()
		if err := os.Remove(f.Name()); err != nil {
			t.Log(err)
		}
	}()

	_, err = f.WriteString(test.src)
	if err != nil {
		t.Fatal(err)
	}

	n, err = parse.ParseFile(token.NewFileSet(), f.Name(), "")
}
Beispiel #12
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
}
Beispiel #13
0
Datei: comp.go Projekt: enex/RUN
// 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) error {
	var c compiler

	c.fset = token.NewFileSet()
	f, err := parse.ParseFile(c.fset, path, nil)
	if err != nil {
		return err
	}

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

	c.fp = fp
	c.compFile(f)

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}
Beispiel #14
0
func handleFileTests(t *testing.T, tests []Test) {
	for _, test := range tests {
		f, err := parse.ParseFile(token.NewFileSet(), test.name, test.src)
		checkTest(t, test, f, err)
	}
}