Skip to content

Commit 049f953

Browse files
committed
Use absolute locations in all jump/call/choice/commit instructions.
1 parent 76cfd01 commit 049f953

3 files changed

Lines changed: 52 additions & 50 deletions

File tree

gnuplot-context.el

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,10 @@ These have to be compiled from the Gnuplot source tree using
411411

412412

413413
(eval-when-compile
414-
;; Compile a single pattern into a list of instructions. Leaves any
415-
;; calls to other rules as symbolic instructions (call SYMBOL); these
416-
;; are resolved into offsets by `gnuplot-compile-grammar', below.
414+
;; Compile a single pattern into a list of instructions. Leaves
415+
;; calls to other rules as symbolic instructions (call SYMBOL) and
416+
;; jumps, commits etc. as relative offsets; these are resolved into
417+
;; absolute locations by `gnuplot-compile-grammar', below.
417418
(defun gnuplot-compile-pattern (pat)
418419
(cond
419420
;; Strings match a single token literally
@@ -620,24 +621,33 @@ These have to be compiled from the Gnuplot source tree using
620621
(setf (aref object-code i) '(return)
621622
i (1+ i))))
622623

623-
;; Resolve symbolic jumps
624+
;; Resolve symbolic and relative jumps
624625
(let ((pattern-name nil))
625626
(dotimes (i (length object-code))
626627
(let ((inst (aref object-code i)))
627628
(case (car inst)
628629
((label)
629630
(setq pattern-name (cadr inst)))
630631

631-
((jump call)
632-
(if (symbolp (cadr inst))
633-
(let* ((name (cadr inst))
634-
(location (gethash name name->offset)))
635-
(if (not location)
636-
(error
637-
(concat "gnuplot-compile-grammar: "
638-
"No rule found for symbol `%s' in pattern `%s'")
639-
name pattern-name))
640-
(setcdr inst `(,location t ,name)))))))))
632+
((jump call choice commit)
633+
(cond
634+
((symbolp (cadr inst))
635+
(let* ((name (cadr inst))
636+
(location (gethash name name->offset)))
637+
(if (not location)
638+
(error
639+
(concat "gnuplot-compile-grammar: "
640+
"No rule found for symbol `%s' in pattern `%s'")
641+
name pattern-name))
642+
(setcdr inst `(,location ,name))))
643+
644+
((numberp (cadr inst))
645+
(let* ((offset (cadr inst))
646+
(location (+ offset i)))
647+
(setcdr inst `(,location))))
648+
649+
(t
650+
(error "gnuplot-compile-grammar: bad instruction %s" inst))))))))
641651
object-code))))
642652

643653
;;; The grammar.
@@ -1657,7 +1667,7 @@ Set by `gnuplot-match-pattern'. See also `gnuplot-info-at-point'.")
16571667
16581668
Each entry is of the form (NAME BEGIN END), where NAME is the
16591669
name specified in the (capture NAME PATTERN) form in the
1660-
`gnuplop-compiled-grammar' source, BEGIN is the tail of the token
1670+
`gnuplot-compiled-grammar' source, BEGIN is the tail of the token
16611671
list beginning the capture group, and END is the tail of the
16621672
token list just after the end of the capture group.")
16631673

@@ -1770,20 +1780,17 @@ there."
17701780
(fail)
17711781
(advance)))
17721782

1773-
;; (jump OFFSET FIXED): jump to instruction at PC + OFFSET,
1774-
;; or directly to OFFSET if FIXED is non-nil
1783+
;; (jump LOCATION): jump to instruction at LOCATION
17751784
((jump)
1776-
(let ((offset (cadr inst))
1777-
(fixed (caddr inst)))
1778-
(setq jump (if fixed offset (+ pc offset)))))
1785+
(let ((location (cadr inst)))
1786+
(setq jump location)))
17791787

1780-
;; (call OFFSET FIXED): push the next instruction as a
1781-
;; return location and jump like (jump), above
1788+
;; (call LOCATION): push the next instruction as a
1789+
;; return location and jump
17821790
((call)
1783-
(let ((offset (cadr inst))
1784-
(fixed (caddr inst)))
1791+
(let ((location (cadr inst)))
17851792
(push `(return ,(+ pc 1)) stack)
1786-
(setq jump (if fixed offset (+ pc offset)))))
1793+
(setq jump location)))
17871794

17881795
;; (return): return to address at topmost RETURN record on
17891796
;; stack, or stop matching and return if stack is empty
@@ -1799,22 +1806,22 @@ there."
17991806
(r-pc (cadr r)))
18001807
(setq jump r-pc))))
18011808

1802-
;; (choice OFFSET): push PC + OFFSET onto the stack of
1809+
;; (choice LOCATION): push LOCATION onto the stack of
18031810
;; backtracking points and continue at next instruction
18041811
((choice)
1805-
(let ((offset (cadr inst)))
1806-
(push `(,stack ,tokens ,(+ pc offset) ,gnuplot-captures
1812+
(let ((location (cadr inst)))
1813+
(push `(,stack ,tokens ,location ,gnuplot-captures
18071814
,progress)
18081815
backtrack)))
18091816

1810-
;; (commit OFFSET): discard most recent backtrack point
1811-
;; and jump to PC + OFFSET
1817+
;; (commit LOCATION): discard most recent backtrack point
1818+
;; and jump to LOCATION
18121819
((commit)
1813-
(let ((offset (cadr inst)))
1820+
(let ((location (cadr inst)))
18141821
(if (not backtrack)
18151822
(error "no more backtrack points in commit"))
18161823
(pop backtrack)
1817-
(setq jump (+ pc offset))))
1824+
(setq jump location)))
18181825

18191826
;; (fail): force this match to fail, going back to most
18201827
;; recent backtrack point

gnuplot-debug-context.el

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
;;
2+
;; debugging utilities for the gnuplot-mode context matcher
3+
;;
4+
5+
(require 'gnuplot-test-context) ; for gnuplot-simplify-tokens
16

27
(defun gnuplot-unload ()
38
(interactive)

gnuplot-test-context.el

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141
(intern (gnuplot-token-id token)))))
4242
tokens))
4343

44-
;; compile a single pattern to vector form
44+
;; compile a single pattern to usable form
4545
(eval-when-compile
4646
(defun gnuplot-compile-pattern-1 (pattern)
47-
(vconcat (gnuplot-compile-pattern pattern) [(return)])))
47+
(gnuplot-compile-grammar `((rule ,pattern)) 'rule)))
4848

4949
;; match a string
5050
(defun gnuplot-match-string (string rule)
@@ -194,10 +194,6 @@
194194
("," :none)
195195
("]" :none)))
196196

197-
(deftest gnuplot-parenthesized-expression ()
198-
(should-match parenthesized-expression
199-
("(sum = sum + $2, sum/2)")))
200-
201197
(deftest gnuplot-function-call ()
202198
(should-match function-call
203199
"abs(2)"
@@ -232,6 +228,11 @@
232228
("x=y=3, garbage" '(\, garbage))
233229
("f(a) = y(x) = 5")))
234230

231+
;; parenthesized exprs (including assignments)
232+
(deftest gnuplot-parenthesized-expression ()
233+
(should-match parenthesized-expression
234+
("(sum = sum + $2, sum/2)")))
235+
235236
;; axis ranges
236237
(deftest gnuplot-axis-range ()
237238
(should-match axis-range
@@ -299,25 +300,15 @@
299300
(deftest gnuplot-plot-command ()
300301
(should-match plot-command
301302
("plot sin(x) with impulses")
302-
303303
("plot x w points, x**2")
304-
305304
("plot [ ] [-2:5] tan(x), 'data.1' with l")
306-
307305
("plot 'leastsq.dat' w i")
308-
309306
("plot 'exper.dat' w lines, 'exper.dat' notitle w errorbars")
310-
311307
("plot sin(x) with linesp lt 1 pt 3, cos(x) with linesp lt 1 pt 4")
312-
313308
("plot 'data' with points pointtype 3 pointsize 2")
314-
315309
("plot 'data' using 1:2:4 with points pt 5 pointsize variable")
316-
317310
("plot 'd1' t \"good\" w l lt 2 lw 3, 'd2' t \"bad\" w l lt 2 lw 1")
318-
319311
("plot x*x with filledcurve closed, 40 with filledcurve y1=10")
320-
321312
("plot x*x, (x>=-5 && x<=5 ? 40 : 1/0) with filledcurve y1=10 lt 8")))
322313

323314
;;; set cntrparam
@@ -332,8 +323,7 @@
332323
("cntrparam levels 10")
333324
("cntrparam levels incremental 100,50")))
334325

335-
336-
326+
337327
;;
338328
;; test by parsing all the demos
339329
;;

0 commit comments

Comments
 (0)