Skip to content

Commit

Permalink
Revert "Work on annotating multiple files (multiple -f provided)."
Browse files Browse the repository at this point in the history
This appears to be a dead end...

This reverts commit 3a3a6c2.

Revert "Work on annotating multiple files (multiple -f provided)."

This reverts commit fb42783.

Revert "Work on annotating multiple files (multiple -f provided)."

This reverts commit 5dbafa3.

Revert "Work on annotating multiple files (multiple -f provided)."

This reverts commit bb09b88.

Revert "Work on annotating multiple files (multiple -f provided)."

This reverts commit 3e0c70b.
  • Loading branch information
xonixx committed Aug 17, 2022
1 parent 3e0c70b commit 070521a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 103 deletions.
72 changes: 13 additions & 59 deletions cover/cover.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,22 @@ import (
"fmt"
"github.com/benhoyt/goawk/internal/ast"
"github.com/benhoyt/goawk/parser"
"os"
"strings"
)

// TODO mention thread-safety
type annotator struct {
covermode string
currentFileName string
annotationIdx int
boundaries map[int]ast.Boundary
fileNames map[int]string
program *parser.Program
covermode string
annotationIdx int
boundaries map[int]ast.Boundary
}

func NewAnnotator(covermode string, parserConfig *parser.ParserConfig) *annotator {
return &annotator{covermode, "", 0,
map[int]ast.Boundary{}, map[int]string{}, parseProg("", parserConfig)}
}

var onlyParseParserConfig = &parser.ParserConfig{
DebugWriter: os.Stderr,
OnlyParseToAST: true,
}

func (annotator *annotator) AddFile(filename string, code []byte) {
prog, err := parser.ParseProgram(code, onlyParseParserConfig)
if err != nil {
panic(err) // at this point the code should be already valid
}
annotator.currentFileName = filename
annotator.annotate(prog)
annotator.appendProgram(prog)
}

func (annotator *annotator) appendProgram(prog *parser.Program) {
annotator.program.Begin = append(annotator.program.Begin, prog.Begin...)
annotator.program.End = append(annotator.program.End, prog.End...)
annotator.program.Actions = append(annotator.program.Actions, prog.Actions...)
annotator.program.Functions = append(annotator.program.Functions, prog.Functions...)
}

func (annotator *annotator) GetResultProgram() *parser.Program {
annotator.addCoverageEnd()
program := annotator.program
program.Resolve()
err := program.Compile()
if err != nil {
panic(err)
}
return program
}

func (annotator *annotator) annotate(prog *parser.Program) {
//annotator := &annotator{covermode, 0, map[int]ast.Boundary{}}
func Annotate(prog *parser.Program, covermode string) {
annotator := &annotator{covermode, 0, map[int]ast.Boundary{}}
prog.Begin = annotator.annotateStmtsList(prog.Begin)
prog.Actions = annotator.annotateActions(prog.Actions)
prog.End = annotator.annotateStmtsList(prog.End)
prog.Functions = annotator.annotateFunctions(prog.Functions)
//annotator.addCoverageEnd(prog)
annotator.addCoverageEnd(prog)
}

func (annotator *annotator) annotateActions(actions []ast.Action) (res []ast.Action) {
Expand Down Expand Up @@ -137,38 +94,35 @@ func (annotator *annotator) annotateStmts(stmts ast.Stmts) (res ast.Stmts) {
return
// TODO complete handling of if/else/else if
}

func (annotator *annotator) trackStatement(statements []ast.Stmt) ast.Stmt {
op := "=1"
if annotator.covermode == "count" {
op = "++"
}
annotator.annotationIdx++
annotator.fileNames[annotator.annotationIdx] = annotator.currentFileName
annotator.boundaries[annotator.annotationIdx] = ast.Boundary{
Start: statements[0].(ast.SimpleStmt).GetBoundary().Start,
End: statements[len(statements)-1].(ast.SimpleStmt).GetBoundary().End,
}
return parseProg(fmt.Sprintf(`BEGIN { __COVER[%d]%s }`, annotator.annotationIdx, op), nil).Begin[0][0]
return parseProg(fmt.Sprintf(`BEGIN { __COVER[%d]%s }`, annotator.annotationIdx, op)).Begin[0][0]
}

func parseProg(code string, parserConfig *parser.ParserConfig) *parser.Program {
prog, err := parser.ParseProgram([]byte(code), parserConfig)
func parseProg(code string) *parser.Program {
prog, err := parser.ParseProgram([]byte(code), nil)
if err != nil {
panic(err)
}
return prog
}

func (annotator *annotator) addCoverageEnd() {
func (annotator *annotator) addCoverageEnd(prog *parser.Program) {
var code strings.Builder
code.WriteString("END {\n")
code.WriteString("END {")
for i := 1; i <= annotator.annotationIdx; i++ {
code.WriteString(fmt.Sprintf("__COVER_DATA[%d]=\"%s:%s\"\n",
i, annotator.fileNames[i], renderCoverBoundary(annotator.boundaries[i])))
code.WriteString(fmt.Sprintf("__COVER_BOUNDARY[%d]=\"%s\"\n", i, renderCoverBoundary(annotator.boundaries[i])))
}
code.WriteString("}")
annotator.program.End = append(annotator.program.End, parseProg(code.String(), nil).End...)
prog.End = append(prog.End, parseProg(code.String()).End...)
}

func renderCoverBoundary(boundary ast.Boundary) string {
Expand Down
28 changes: 5 additions & 23 deletions goawk.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ argsLoop:
DebugTypes: debugTypes,
DebugWriter: os.Stderr,
}
//fmt.Println("before parse")
prog, err := parser.ParseProgram(src, parserConfig)
if err != nil {
if err, ok := err.(*parser.ParseError); ok {
Expand All @@ -264,34 +263,17 @@ argsLoop:
}
errorExitf("%s", err)
}
//fmt.Println("after parse")

if covermode != "" {
annotator := cover.NewAnnotator(covermode, parserConfig)
// Read source: the concatenation of all source files specified
for _, progFile := range progFiles {
var f *os.File
if progFile == "-" { // TODO probably we should not annotate code of "-"
f = os.Stdin // TODO are we able to read STDIN twice??
} else {
f, err = os.Open(progFile)
if err != nil {
errorExit(err)
}
}
b, err := ioutil.ReadAll(f)
if err != nil {
errorExit(err)
}
annotator.AddFile(progFile, b)
_ = f.Close()
}
prog = annotator.GetResultProgram()

cover.Annotate(prog, covermode) // TODO shall we adjust parsed prog as well, or maybe re-parse?
if coverprofile == "" {
fmt.Fprintln(os.Stdout, prog)
os.Exit(0)
}
err := prog.Compile() // recompile for annotations to take an effect
if err != nil {
errorExitf("%s", err)
}
}

if debug {
Expand Down
28 changes: 7 additions & 21 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ type ParserConfig struct {
// Map of named Go functions to allow calling from AWK. See docs
// on interp.Config.Funcs for details.
Funcs map[string]interface{}

// Disable resolving/compiling steps for the cases when we only need parsing
// to AST, like for coverage annotation.
OnlyParseToAST bool
}

// ParseProgram parses an entire AWK program, returning the *Program
Expand All @@ -67,7 +63,6 @@ func ParseProgram(src []byte, config *ParserConfig) (prog *Program, err error) {
p := parser{lexer: lexer}
if config != nil {
p.debugTypes = config.DebugTypes
p.onlyParseToAST = config.OnlyParseToAST
p.debugWriter = config.DebugWriter
p.nativeFuncs = config.Funcs
}
Expand All @@ -77,10 +72,8 @@ func ParseProgram(src []byte, config *ParserConfig) (prog *Program, err error) {
// Parse into abstract syntax tree
prog = p.program()

if !p.onlyParseToAST {
// Compile to virtual machine code
err = prog.Compile()
}
// Compile to virtual machine code
err = prog.Compile()

return prog, err
}
Expand All @@ -104,7 +97,6 @@ type Program struct {
Scalars map[string]int
Arrays map[string]int
Compiled *compiler.Program
Resolve func() // TODO
}

// String returns an indented, pretty-printed version of the parsed
Expand Down Expand Up @@ -140,7 +132,7 @@ type parser struct {
prevTok Token // previously lexed token
val string // string value of last token (or "")

startPos Position // TODO
startPos Position

// Parsing state
inAction bool // true if parsing an action (false in BEGIN or END)
Expand All @@ -160,9 +152,8 @@ type parser struct {
nativeFuncs map[string]interface{}

// Configuration and debugging
debugTypes bool // show variable types for debugging
onlyParseToAST bool // Disable resolving/compiling steps for the cases when we only need parsing to AST, like for coverage annotation.
debugWriter io.Writer // where the debug output goes
debugTypes bool // show variable types for debugging
debugWriter io.Writer // where the debug output goes
}

func (p *parser) markStartPos() {
Expand Down Expand Up @@ -210,13 +201,8 @@ func (p *parser) program() *Program {
p.optionalNewlines()
}

prog.Resolve = func() {
p.resolveUserCalls(prog)
p.resolveVars(prog)
}
if !p.onlyParseToAST {
prog.Resolve()
}
p.resolveUserCalls(prog)
p.resolveVars(prog)
p.checkMultiExprs()

return prog
Expand Down

0 comments on commit 070521a

Please sign in to comment.