Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SHELL_FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The in-shell `help` command mirrors these feature categories: run `help` for a c

## Builtins

- ✅ `awk [-F SEP] [-v NAME=VALUE] ['PROGRAM'|-f PROGRAM-FILE] [FILE]...` — pattern scanning and text processing; supports BEGIN/main/END rules, read-only fields (`$0`, `$1`, `$NF`), `NF`/`NR`/`FNR`/`FILENAME`, `FS`/`OFS`/`ORS`, `print`, `printf`, scalar assignment, arithmetic/comparison/boolean expressions, regex patterns and `~`/`!~`, string concatenation, `if`/`else`, `next`, and scalar builtins (`length`, `substr`, `index`, `tolower`, `toupper`, `int`); `system()`, command pipes, output redirection, `getline`, arrays, loops, regex `FS`, and field mutation are rejected or deferred
- ✅ `awk [-F SEP] [-v NAME=VALUE] ['PROGRAM'|-f PROGRAM-FILE] [FILE]...` — pattern scanning and text processing; supports BEGIN/main/END rules, fields and field mutation (`$0`, `$1`, `$NF`), `NF`/`NR`/`FNR`/`FILENAME`, `FS`/`OFS`/`ORS`, regex `FS`, `print`, `printf`, scalar and associative array assignment, `split`, `in`, `delete`, `for`, `while`, `break`, `continue`, range patterns, arithmetic/comparison/boolean expressions, regex patterns and `~`/`!~`, string concatenation, `if`/`else`, `next`, `ENVIRON`, and scalar builtins (`length`, `substr`, `index`, `tolower`, `toupper`, `int`); `system()`, command pipes, output redirection, `getline`, user-defined functions, and many POSIX/GNU awk builtins remain rejected or deferred
- ✅ `break` — exit the innermost `for` loop
- ✅ `cat [-AbeEnstTuv] [FILE]...` — concatenate files to stdout; supports line numbering, blank squeezing, and non-printing character display
- ✅ `continue` — skip to the next iteration of the innermost `for` loop
Expand Down
2 changes: 1 addition & 1 deletion analysis/symbols_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ var builtinAllowedSymbols = []string{
"slices.Reverse", // 🟢 reverses a slice in-place; pure function, no I/O.
"slices.SortFunc", // 🟢 sorts a slice with a comparison function; pure function, no I/O.
"slices.SortStableFunc", // 🟢 stable sort with a comparison function; pure function, no I/O.
"strings.Repeat", // 🟢 returns a string of n repetitions; pure function, no I/O.
"strconv.Atoi", // 🟢 string-to-int conversion; pure function, no I/O.
"strconv.ErrRange", // 🟢 sentinel error value for overflow; pure constant.
"strconv.FormatBool", // 🟢 bool-to-string conversion; pure function, no I/O.
Expand All @@ -661,6 +660,7 @@ var builtinAllowedSymbols = []string{
"strings.Join", // 🟢 concatenates a slice of strings with a separator; pure function, no I/O.
"strings.NewReader", // 🟢 wraps a string as an io.Reader; pure in-memory, no I/O.
"strings.ReplaceAll", // 🟢 replaces all occurrences of a substring; pure function, no I/O.
"strings.Repeat", // 🟢 returns a string of n repetitions; pure function, no I/O.
"strings.Split", // 🟢 splits a string by separator into a slice; pure function, no I/O.
"strings.ToLower", // 🟢 converts string to lowercase; pure function, no I/O.
"strings.ToUpper", // 🟢 converts string to uppercase; pure function, no I/O.
Expand Down
54 changes: 54 additions & 0 deletions builtins/awk/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,50 @@ type ifStmt struct {

func (*ifStmt) stmtNode() {}

type forInStmt struct {
varName string
arrayName string
body []stmt
}

func (*forInStmt) stmtNode() {}

type forStmt struct {
init expr
cond expr
post expr
body []stmt
}

func (*forStmt) stmtNode() {}

type whileStmt struct {
cond expr
body []stmt
}

func (*whileStmt) stmtNode() {}

type nextStmt struct{}

func (*nextStmt) stmtNode() {}

type breakStmt struct{}

func (*breakStmt) stmtNode() {}

type continueStmt struct{}

func (*continueStmt) stmtNode() {}

type deleteStmt struct {
name string
index expr
all bool
}

func (*deleteStmt) stmtNode() {}

type exprStmt struct {
x expr
}
Expand Down Expand Up @@ -86,6 +126,13 @@ type varExpr struct {

func (*varExpr) exprNode() {}

type arrayRefExpr struct {
name string
index expr
}

func (*arrayRefExpr) exprNode() {}

type fieldExpr struct {
index expr
}
Expand Down Expand Up @@ -113,6 +160,13 @@ type binaryExpr struct {

func (*binaryExpr) exprNode() {}

type rangeExpr struct {
start expr
end expr
}

func (*rangeExpr) exprNode() {}

type assignExpr struct {
op string
left expr
Expand Down
17 changes: 9 additions & 8 deletions builtins/awk/awk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
// awk [OPTION]... -f program-file [FILE]...
//
// This implements a practical, intentionally restricted awk profile: program
// loading from an inline argument or -f files, -F one-character field
// loading from an inline argument or -f files, -F field
// separators, -v scalar variables, BEGIN/main/END rules, print and printf,
// scalar assignment, if/else, next, arithmetic/comparison/boolean expressions,
// regex patterns and match operators, string concatenation, scalar built-in
// functions, and read-only fields/built-in variables such as $0, $1, NF, NR,
// FNR, FILENAME, FS, OFS, and ORS.
// scalar and associative array assignment, if/else, for/while loops, next,
// arithmetic/comparison/boolean expressions, regex patterns and match
// operators, regex field separators, string concatenation, scalar built-in
// functions, split, delete, ENVIRON, and field/built-in variables such as $0,
// $1, NF, NR, FNR, FILENAME, FS, OFS, and ORS.
//
// Blocked or deferred features include system(), command pipes, output
// redirection, getline, arrays, loops, user-defined functions, regex FS, and
// field mutation/$0 rebuilding.
// redirection, getline, user-defined functions, and many additional POSIX/GNU
// awk builtins.
package awk

import (
Expand Down Expand Up @@ -93,7 +94,7 @@ func registerFlags(fs *builtins.FlagSet) builtins.HandlerFunc {
help := fs.BoolP("help", "h", false, "print usage and exit")
var orderedOptions []orderedOption
fieldSep := fieldSeparatorOption{options: &orderedOptions}
fs.VarP(&fieldSep, "field-separator", "F", "use a single-character input field separator")
fs.VarP(&fieldSep, "field-separator", "F", "use an input field separator regular expression")
var programFiles stringList
fs.VarP(&programFiles, "file", "f", "read awk program from file")
assignments := assignmentOption{options: &orderedOptions}
Expand Down
Loading
Loading