aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-08-30 22:27:48 +0200
committerHimbeer <himbeer@disroot.org>2024-08-30 22:27:48 +0200
commitbb80a9c772b077bdc7173055e88c3e9f8bb1c35b (patch)
treedaf2a813e4d33983a0eeab7f78f190da6c6f3eac
parent4019e81876fdceccf2db58182160d996546adaa5 (diff)
Allow the use of local variables in expressions
-rw-r--r--GRAMMAR.txt3
-rw-r--r--expression.go13
-rw-r--r--generate.go15
-rw-r--r--parse.go28
4 files changed, 57 insertions, 2 deletions
diff --git a/GRAMMAR.txt b/GRAMMAR.txt
index bd7b4d4..68177fc 100644
--- a/GRAMMAR.txt
+++ b/GRAMMAR.txt
@@ -26,10 +26,11 @@ term -> numeral ( ( "<<" | ">>" ) numeral )*
numeral -> factor ( ( "+" | "-" ) factor )*
factor -> unary ( ( "*" | "/" ) unary )*
unary -> ( "-" | "!" | "~" )? primary
-primary -> grouping | literal | call
+primary -> grouping | literal | call | variable
grouping -> "(" expression ")"
literal -> string | number
string -> STRING*
number -> NUMBER IDENTIFIER
call -> IDENTIFIER "(" arg? ")"
arg -> expression ( "," arg )?
+variable -> IDENTIFIER
diff --git a/expression.go b/expression.go
index 285cac3..9752730 100644
--- a/expression.go
+++ b/expression.go
@@ -323,3 +323,16 @@ type argument struct {
value exprExpr
next *argument
}
+
+type varExpr struct {
+ name string
+ ln int
+}
+
+func (v *varExpr) markExpr() {}
+
+func (v *varExpr) markExprExpr() {}
+
+func (v *varExpr) markPrimaryExpr() {}
+
+func (v *varExpr) line() int { return v.ln }
diff --git a/generate.go b/generate.go
index 187ec8f..5701cb1 100644
--- a/generate.go
+++ b/generate.go
@@ -476,3 +476,18 @@ func (c *callExpr) generate(w io.Writer) (string, error) {
return ret, nil
}
+
+func (v *varExpr) generate(w io.Writer) (string, error) {
+ ok, mutable := isDeclared(v.name, false)
+ if !ok {
+ return "", errUndeclared{name: v.name, line: v.line()}
+ }
+
+ if mutable {
+ reg := allocReg()
+ fmt.Fprintf(w, "%s =w loadl %%%s\n", reg, v.name)
+ return reg, nil
+ }
+
+ return localConsts[currentFunc][v.name], nil
+}
diff --git a/parse.go b/parse.go
index 7b4469e..c6b21f0 100644
--- a/parse.go
+++ b/parse.go
@@ -801,6 +801,14 @@ func parsePrimary(toks *tokens) (primaryExpr, error) {
return call, nil
}
+ variable, err := parseVariable(toks)
+ if err != nil {
+ return nil, err
+ }
+ if variable != nil {
+ return variable, nil
+ }
+
return nil, expectedPrimary{got: toks.current()}
}
@@ -923,9 +931,14 @@ func parseCall(toks *tokens) (*callExpr, error) {
return nil, nil
}
- if err := toks.mustMatch(lparen); err != nil {
+ ok, err := toks.match(lparen)
+ if err != nil {
return nil, err
}
+ if !ok {
+ toks.unreadTokens(2)
+ return nil, nil
+ }
args, err := parseArg(toks)
if err != nil {
@@ -970,3 +983,16 @@ func parseArg(toks *tokens) (*argument, error) {
return &argument{value: arg, next: next}, nil
}
+
+func parseVariable(toks *tokens) (*varExpr, error) {
+ nameTok, ok := toks.consumeToken()
+ if !ok {
+ return nil, unexpectedEOF
+ }
+ if nameTok.kind != identifier {
+ toks.unreadToken()
+ return nil, nil
+ }
+
+ return &varExpr{name: nameTok.value, ln: nameTok.line}, nil
+}