nx_eqparse_gate.nx source
↩ module page · 67 lines · 3887 B
1// nx_eqparse_gate.nx -- can a typed equation be read correctly, and are the things outside scope REFUSED?
2// license_tier: ORIGINAL expect_exit: 0
3import "syscalls.nx"
4import "nx_eqparse_lib.nx"
5import "nx_gate_verdict.nx"
6
7func eg_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i }
8func eg_p(s: *u8, o: *i64) -> i64 { return eq_parse(s, eg_slen(s), o) }
9
10func main() -> i64 {
11 let ctr: *i64 = gv_ctr()
12 gv_head("=== NX-EQPARSE-GATE -- reading an equation a person actually typed ===" as *u8)
13 let o: *i64 = (sys_mmap(24)) as *i64
14
15 // 3x + 4 = 19 -> 3x - 15 = 0
16 gv_check_eq("fixture-reached-the-condition: a plain linear equation parses" as *u8, eg_p("3x+4=19" as *u8, o), EQ_OK, ctr)
17 gv_check_eq("the-x-COEFFICIENT-is-read" as *u8, o[1], 3, ctr)
18 gv_check_eq("the-RIGHT-hand-side-is-SUBTRACTED-which-is-the-move-a-person-makes-by-hand" as *u8, o[0], 4 - 19, ctr)
19
20 // Whitespace must not change the reading.
21 gv_check_eq("SPACES-are-ignored-so-a-typed-equation-reads-the-same-either-way" as *u8, eg_p("3x + 4 = 19" as *u8, o), EQ_OK, ctr)
22 gv_check_eq("and-produces-the-IDENTICAL-constant" as *u8, o[0], 0 - 15, ctr)
23
24 // x^2 - 5x + 6 = 0
25 gv_check_eq("a-QUADRATIC-parses" as *u8, eg_p("x^2-5x+6=0" as *u8, o), EQ_OK, ctr)
26 gv_check_eq("a-BARE-x-squared-means-ONE-x-squared-not-zero" as *u8, o[2], 1, ctr)
27 gv_check_eq("a-NEGATIVE-middle-term-keeps-its-sign" as *u8, o[1], 0 - 5, ctr)
28 gv_check_eq("and-the-constant-is-read" as *u8, o[0], 6, ctr)
29
30 // Terms on both sides must combine: 2x + 1 = x + 5 -> x - 4 = 0
31 gv_check_eq("x-on-BOTH-SIDES-parses" as *u8, eg_p("2x+1=x+5" as *u8, o), EQ_OK, ctr)
32 gv_check_eq("and-the-x-terms-COMBINE-across-the-equals" as *u8, o[1], 1, ctr)
33 gv_check_eq("and-so-do-the-constants" as *u8, o[0], 0 - 4, ctr)
34
35 // A leading minus is a sign, not a subtraction of nothing.
36 gv_check_eq("a-LEADING-MINUS-parses" as *u8, eg_p("-x+3=0" as *u8, o), EQ_OK, ctr)
37 gv_check_eq("and-gives-a-negative-coefficient" as *u8, o[1], 0 - 1, ctr)
38
39 // ---- REFUSALS, EACH NAMING ITS RULE -------------------------------------------------------------
40 gv_check_eq("neg-control-an-EXPRESSION-with-no-equals-is-not-an-equation-and-is-REFUSED" as *u8,
41 eg_p("3x+4" as *u8, o), EQ_ERR_NO_EQUALS, ctr)
42 gv_check_eq("neg-control-TWO-equals-signs-are-REFUSED" as *u8,
43 eg_p("1=2=3" as *u8, o), EQ_ERR_TWO_EQUALS, ctr)
44 gv_check_eq("neg-control-a-CUBE-is-outside-this-subset-and-says-so-rather-than-guessing" as *u8,
45 eg_p("x^3=8" as *u8, o), EQ_ERR_DEGREE, ctr)
46 gv_check_eq("neg-control-an-UNSUPPORTED-character-is-REFUSED-by-name" as *u8,
47 eg_p("3y+1=0" as *u8, o), EQ_ERR_BADCHAR, ctr)
48 gv_check_eq("neg-control-an-equation-with-NO-X-has-nothing-to-solve-for" as *u8,
49 eg_p("3+4=7" as *u8, o), EQ_ERR_NO_X, ctr)
50 gv_check_eq("neg-control-EMPTY-input-is-refused" as *u8, eq_parse("" as *u8, 0, o), EQ_ERR_EMPTY, ctr)
51
52 gv_values_head()
53 let r1: i64 = eg_p("3x+4=19" as *u8, o)
54 gv_kv("linear_3x_plus_4_eq_19_x_coefficient" as *u8, o[1])
55 gv_kv("linear_3x_plus_4_eq_19_constant" as *u8, o[0])
56 let r2: i64 = eg_p("x^2-5x+6=0" as *u8, o)
57 gv_kv("quadratic_x2_coefficient" as *u8, o[2])
58 gv_kv("quadratic_x_coefficient" as *u8, o[1])
59 gv_kv("quadratic_constant" as *u8, o[0])
60 gv_kv("parse_ok_code" as *u8, r1 + r2)
61 gv_kv("no_equals_error_code" as *u8, EQ_ERR_NO_EQUALS)
62
63 let rc: i64 = gv_verdict("eqparse-gate" as *u8, ctr,
64 "a typed equation in one variable up to degree two is read into coefficients with the right-hand side subtracted as a person would do it, implicit and negative coefficients handled, and everything outside the declared subset refused by a rule that names itself" as *u8)
65 sys_exit(rc)
66 return rc
67}