Adds receivers to filter and point structs

This commit is contained in:
Brian Evans 2019-07-17 16:18:58 -07:00
parent 5a85f9cc8f
commit e2b5936197
7 changed files with 232 additions and 66 deletions

2
.gitignore vendored
View File

@ -12,3 +12,5 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Binary from `go build`
filtress

View File

@ -77,13 +77,6 @@ MOD [op]int
. . .
Set fade time:
# If set below zero, becomes zero
FAD [op]int
. . .
Doing loops:
# The int after BEG represents the number of times to loop
# At present, loops may not be nested

69
main.go
View File

@ -1,5 +1,14 @@
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"tildegit.org/sloum/filtress/parser"
)
type point struct {
x int
y int
@ -7,21 +16,61 @@ type point struct {
maxY int
}
type color int
type mode int
type filter struct {
max int
min int
val int
}
type filterState struct {
red color
green color
blue color
alpha color
red filter
green filter
blue filter
alpha filter
location point
mod mode
register int
fade uint
loop uint
mode filter
}
var variables = map[string]int{}
func openFileFromPath(path string) *os.File {
file, err := os.Open(path)
if err != nil {
panic(err)
}
return file
}
func main() {
// Handle checking filter file argument
flag.Parse()
posArgs := flag.Args()
if len(posArgs) > 1 || len(posArgs) < 1 {
panic(fmt.Sprintf("Input error: Too many positional arguments. Expected one, received %d", len(flag.Args())))
}
fpath := posArgs[0]
fext := strings.ToUpper(filepath.Ext(fpath))
_, fname := filepath.Split(fpath)
if fext != ".FRS" {
panic(fmt.Sprintf("Input error: Incorrect filetype. Expected .FRS, received \".%s\"", fext))
}
// Open file and parse
fmt.Println("Filtress v0.2.0")
filterFile := openFileFromPath(fpath)
parser := parser.NewParser(filterFile)
fmt.Printf("Parsing file: %s ...\n", fname)
tree := parser.Parse()
if len(tree.Loops) > 0 {
fmt.Printf("File has %d procedures\n", len(tree.Loops))
fmt.Println("File is valid")
} else {
fmt.Println("Invalid input file")
}
fmt.Print(tree)
fmt.Println()
}

View File

@ -1,4 +1,4 @@
package parse
package parser
import (
"bufio"
@ -48,11 +48,12 @@ func (s *scanner) unread() {
func (s *scanner) scan() Token {
for {
char := s.read()
if isWhitespace(char) {
s.unread()
return s.scanWhitespace()
s.scanWhitespace()
} else if isLetter(char) {
s.unread()
return s.scanText()
@ -61,19 +62,20 @@ func (s *scanner) scan() Token {
return s.scanNumber()
} else if char == '#' {
s.unread()
return s.scanComment()
s.scanComment()
} else if isOpperator(char) {
return Token{Opperator, string(char)}
} else if char == '\n' {
return Token{Newline,""}
return Token{Newline,"New Line"}
} else if char == ':' {
return Token{Separator,""}
return Token{Separator,":"}
} else if char == eof {
return Token{End, ""}
}
return Token{End, "eof"}
} else {
return Token{Illegal, string(char)}
}
}
}
func (s *scanner) scanWhitespace() Token {

View File

@ -1,4 +1,4 @@
package parse
package parser
import (
"io"
@ -45,11 +45,6 @@ func (p *Parser) scan() (current Token) {
return p.buffer.token
}
for {
if current = p.s.scan(); current.kind != Whitespace && current.kind != Comment {
break
}
}
current = p.s.scan()
p.buffer.token = current
return
@ -70,8 +65,13 @@ func (p *Parser) parseExpressions(equals bool) []Expression {
if t.kind == Opperator {
ex.Opperator = rune(t.val[0])
t = p.scan()
} else {
} else if t.kind == Number || t.kind == Text {
ex.Opperator = '='
} else if t.kind == Newline {
p.unscan()
break
} else {
panic(fmt.Sprintf("Parse error: Invalid token %q on \033[1mline %d\033[0m", t.val, p.row))
}
if t.kind == Number {
@ -86,6 +86,7 @@ func (p *Parser) parseExpressions(equals bool) []Expression {
exprs = append(exprs, ex)
t = p.scan()
if t.kind == Separator {
continue
}
@ -133,17 +134,12 @@ func (p *Parser) parseLoop() Loop {
t := p.scan()
l := Loop{}
if strings.ToUpper(t.val) == "LOOP" {
t = p.scan()
if t.kind == Number {
l.Counter, _ = strconv.Atoi(t.val)
} else {
panic(fmt.Sprintf("Parse error: Loop declared, but not followed by a number on \033[1mline %d\033[0m", p.row))
}
} else {
p.unscan()
l.Counter = 1
}
l.Procedures = make([]Procedure,0, 5)
L:
@ -163,6 +159,9 @@ func (p *Parser) parseLoop() Loop {
case Number:
panic(fmt.Sprintf("Parse error: Number %q outside of procedure call on \033[1mline %d\033[0m", t.val, p.row))
case Text:
if strings.ToUpper(t.val) == "END" {
break L
}
p.unscan()
procedure := p.parseProcedure()
l.Procedures = append(l.Procedures, procedure)
@ -193,8 +192,15 @@ func (p *Parser) Parse() AST {
case Number:
panic(fmt.Sprintf("Parse error: Number %q outside of procedure call on \033[1mline %d\033[0m", t.val, p.row))
case Text:
var loop Loop
if strings.ToUpper(t.val) == "BEG" {
loop = p.parseLoop()
} else {
p.unscan()
loop := p.parseLoop()
loop = Loop{1, make([]Procedure, 0, 1)}
procedure := p.parseProcedure()
loop.Procedures = append(loop.Procedures, procedure)
}
tree.Loops = append(tree.Loops, loop)
}
}
@ -205,8 +211,7 @@ func (p *Parser) Parse() AST {
func isValidProcedure(p string) bool {
switch p {
case "REG", "LOC", "BEG", "END", "RED",
"GRN", "BLU", "APH", "COL", "APY", "MOD",
"FAD":
"GRN", "BLU", "APH", "COL", "APY", "MOD":
return true
}
return false
@ -224,3 +229,5 @@ func isVariable(v string) bool {
func NewParser(r io.Reader) *Parser {
return &Parser{s: NewScanner(r)}
}

96
receivers.go Normal file
View File

@ -0,0 +1,96 @@
package main
import (
"fmt"
"tildegit.org/sloum/filtress/parser"
)
func (f *filter) update(change parser.Expression, vars map[string]int) {
opand := change.Opperand
if change.Variable != "" {
if val, ok := vars[change.Variable]; ok {
opand = val
} else {
panic(fmt.Sprintf("Runtime error: Encountered unknown variable %q", val))
}
}
switch change.Opperator {
case '+':
f.val += opand
case '-':
f.val -= opand
case '*':
f.val *= opand
case '/':
if opand == 0 {
f.val = 1
} else {
f.val /= opand
}
case '=':
f.val = opand
}
if f.val > f.max {
f.val %= f.max
}
if f.val < f.min {
f.val = f.max - f.val%f.max
}
}
func (p *point) update(change []parser.Expression, vars map[string]int) {
var totalX, totalY, val, opand, max int
var target *int
for i, e := range change {
if i == 0 {
target = &totalX
val = p.x
max = p.maxX
} else if i == 1 {
target = &totalY
val = p.y
max = p.maxY
} else {
break
}
if e.Variable != "" {
if val, ok := vars[e.Variable]; ok {
opand = val
} else {
panic(fmt.Sprintf("Runtime error: Encountered unknown variable %q", val))
}
} else {
opand = e.Opperand
}
switch e.Opperator {
case '+':
*target = val + opand
case '-':
*target = val - opand
case '*':
*target = val * opand
case '/':
if opand == 0 {
*target = 1
} else {
*target = val / opand
}
case '=':
*target = opand
}
if *target > max {
*target %= max
}
if *target < 0 {
*target = max - *target%max
}
}
p.x = totalX
p.y = totalY
}

17
test.frs Normal file
View File

@ -0,0 +1,17 @@
# First attempt at a filtress file!!
MOD 1
RED 100
BEG 10
LOC +100:WID
BLU /300
END
#comment
APY +100:+100