Skip to content
Permalink
Browse files

Closes #134. Calls clang instead of go build.

  • Loading branch information...
AZHenley committed Apr 14, 2019
1 parent e5695c4 commit 0708dc38eebca899d80d785be63bdfcdfbd6d274
Showing with 115 additions and 9 deletions.
  1. +11 −9 knox.go
  2. +104 −0 knox_go
20 knox.go
@@ -21,7 +21,7 @@ func main() {
// Flags
timeFlag := flag.Bool("time", false, "Print the time taken by each compiler phase.")
astFlag := flag.Bool("ast", false, "Print the AST.")
goFlag := flag.Bool("go", false, "Print the Go code.")
codeFlag := flag.Bool("code", false, "Print the C code.")
outFlag := flag.String("out", "", "Path for output files.")
nameFlag := flag.String("name", "", "Name for output executable.")
binaryFlag := flag.Bool("binary", true, "Generates executable.")
@@ -49,6 +49,7 @@ func main() {
}

// Builtin functions.
// TODO: Build builtin first in case user's program conflicts.
a = *builtin.Init(&a)

// Type check.
@@ -64,7 +65,7 @@ func main() {
output := emitter.Generate(&a)
elapsedEmitting := time.Since(start)

if *goFlag {
if *codeFlag {
fmt.Println(output)
}

@@ -75,22 +76,23 @@ func main() {
}
local := filepath.Dir(ex) // Get current path.
outputDir := path.Join(local, *outFlag)
outputFile := path.Join(outputDir, "out.go") // TODO: Go files should use Knox file names.
codeFile := path.Join(outputDir, "out.c") // TODO: C files should use Knox file names.
binName := *nameFlag
if binName == "" {
binName = "out"
binName = "a.out"
}
outputBin := path.Join(outputDir, binName)
werr := ioutil.WriteFile(outputFile, []byte(output), 0644)
outputBin := path.Join(outputDir, binName) // TODO: Make the flag specify a file, not just a path.
werr := ioutil.WriteFile(codeFile, []byte(output), 0644)
if werr != nil {
panic(werr)
}

// Invoke Go compiler.
// Invoke compiler.
if *binaryFlag {
cmd := exec.Command("go", "build", "-o", outputBin, outputFile)
_, sterr := cmd.Output()
cmd := exec.Command("clang", codeFile, "-o", outputBin)
sto, sterr := cmd.Output()
if sterr != nil {
fmt.Println(sto)
panic(sterr)
}
}
104 knox_go
@@ -0,0 +1,104 @@
package main

import (
"flag"
"fmt"
"io/ioutil"
"knox/ast"
"knox/builtin"
"knox/emitter"
"knox/lexer"
"knox/parser"
"knox/typechecker"
"os"
"os/exec"
"path"
"path/filepath"
"time"
)

func main() {
// Flags
timeFlag := flag.Bool("time", false, "Print the time taken by each compiler phase.")
astFlag := flag.Bool("ast", false, "Print the AST.")
goFlag := flag.Bool("go", false, "Print the Go code.")
outFlag := flag.String("out", "", "Path for output files.")
nameFlag := flag.String("name", "", "Name for output executable.")
binaryFlag := flag.Bool("binary", true, "Generates executable.")
flag.Parse()
args := flag.Args()

if len(args) == 0 {
panic("Specify file to be compiled.")
}
code, err := ioutil.ReadFile(args[0]) // TODO: Support multiple files.
//code, err := ioutil.ReadFile("examples/chain.knox")
if err != nil {
panic(err)
}

// Lex, parse, and generate the AST.
start := time.Now()
l := lexer.New(string(code) + "\n")
p := parser.New(l)
a := p.Program()
elapsedParsing := time.Since(start)

if *astFlag {
ast.Print(a)
}

// Builtin functions.
// TODO: Build builtin first in case user's program conflicts.
a = *builtin.Init(&a)

// Type check.
start = time.Now()
typechecker.Analyze(&a)
elapsedTypeChecking := time.Since(start)

// Control flow analysis.
//cfa.Analyze(&a)

// Generate code.
start = time.Now()
output := emitter.Generate(&a)
elapsedEmitting := time.Since(start)

if *goFlag {
fmt.Println(output)
}

// Output code.
ex, err := os.Executable()
if err != nil {
panic(err)
}
local := filepath.Dir(ex) // Get current path.
outputDir := path.Join(local, *outFlag)
outputFile := path.Join(outputDir, "out.go") // TODO: Go files should use Knox file names.
binName := *nameFlag
if binName == "" {
binName = "out"
}
outputBin := path.Join(outputDir, binName)
werr := ioutil.WriteFile(outputFile, []byte(output), 0644)
if werr != nil {
panic(werr)
}

// Invoke Go compiler.
if *binaryFlag {
cmd := exec.Command("go", "build", "-o", outputBin, outputFile)
_, sterr := cmd.Output()
if sterr != nil {
panic(sterr)
}
}

if *timeFlag {
fmt.Println(elapsedParsing)
fmt.Println(elapsedTypeChecking)
fmt.Println(elapsedEmitting)
}
}

0 comments on commit 0708dc3

Please sign in to comment.
You can’t perform that action at this time.