diff --git a/data/quadratic_formula.md b/data/quadratic_formula.md index 3f1844b..3a16434 100644 --- a/data/quadratic_formula.md +++ b/data/quadratic_formula.md @@ -1,10 +1,16 @@ -quadratic-formula needs a with b with c -b-squared equals square of b -four-a equals multiplication of 4 with a -four-a-c equals multiplication of four-a with c -discriminant equals subtraction of b-squared with four-a-c -sqrt-discriminant equals square-root of discriminant -negative-b equals subtraction of 0 with b -numerator equals addition of negative-b with sqrt-discriminant -denominator equals multiplication of 2 with a -answer equals division of numerator with denominator \ No newline at end of file +fyi < quadratic formula > +a stores 1 +b stores -2 +c stores 1 + +b-squared stores b times b +four-a stores 4 times a +four-a-c stores four-a times c +discriminant stores b-squared minus four-a-c +sqrt-discriminant stores discriminant raised-to 0.5 +negative-b stores 0 minus b +numerator stores negative-b plus sqrt-discriminant +denominator stores 2 times a +root stores numerator divided-by denominator + +show root \ No newline at end of file diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index ef08074..16d9e70 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -10,21 +10,24 @@ codeable_version(0,0,1). numeric(N) --> [N], {number(N)}. % v3 (Heavily inspired by M2.1 - slide 59) -% chars([X|Y]) --> char(X), chars(Y). -% chars([]) --> []. - char(C) --> [C], { char_type(C, alpha) }. -word([A]) --> [A], {atom(A)}. -word([A1 | A2]) --> [A1], word(A2), {atom(A1)}. +identifier(id(I)) --> [I], {atom(I)}. + +word([W]) --> identifier(id(W)). +word([W1 | W2]) --> [W1], word(W2), {atom(W1)}. strings(S) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. -identifier(id(A)) --> [a]. + +comment(fyi(S)) --> [fyi], strings(S). factor(factor_numeric(F)) --> numeric(F). factor(factor_identifier(F)) --> identifier(F). factor(factor_expression(F)) --> ['('], expr(F), [')']. -term(term_factor(T)) --> factor(T). +sub_term(term_factor(T)) --> factor(T). +sub_term(term_exponent(F1, F2)) --> factor(F1), [raised-to], factor(F2). + +term(T) --> sub_term(T). term(term_times(T1, T2)) --> factor(T1), [times], term(T2). term(term_divide(T1, T2)) --> factor(T1), [divided-by], term(T2). @@ -41,7 +44,7 @@ boolean(is_greater_than(E1, E2)) --> expr(E1), [is-greater-than], expr(E2). boolean(is_less_than(E1, E2)) --> expr(E1), [is-less-than], expr(E2). assignment(assign(I, E)) --> identifier(I), [stores], expr(E). -ternary(t_ternary(B, T, F)) --> expr(T), [if], boolean(B), [otherwise], expr(F). +% ternary(t_ternary(B, T, F)) --> expr(T), [if], boolean(B), [otherwise], expr(F). loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. @@ -50,13 +53,15 @@ show(show_numeric(D)) --> [show], numeric(D). show(show_identifier(I)) --> [show], identifier(I). command(C) --> assignment(C). -command(C) --> ternary(C). +% command(C) --> ternary(C). command(C) --> loop(C). command(C) --> show(C). +command(C) --> comment(C). command(cmd(C1, C2)) --> assignment(C1), [;], command(C2). -command(cmd(C1, C2)) --> ternary(C1), [;], command(C2). +% command(cmd(C1, C2)) --> ternary(C1), [;], command(C2). command(cmd(C1, C2)) --> loop(C1), [;], command(C2). command(cmd(C1, C2)) --> show(C1), [;], command(C2). +command(cmd(C1, C2)) --> comment(C1), [;], command(C2). program(prog(P)) --> command(P). @@ -69,6 +74,7 @@ program(prog(P)) --> command(P). % function_eval(Id, Args, [(Id,t_codeable_functions(Pt))|_],Value). % function_eval(Id, Args, [_|T],Value) :- function_eval(Id, T, Value). + /** * eval(+Node, +EnvIn, -EnvOut, -ValueOut) * @@ -82,6 +88,8 @@ program(prog(P)) --> command(P). eval(prog(P), EnvIn, EnvOut, ValueOut) :- eval(P, EnvIn, EnvOut, ValueOut). +eval(fyi(S), EnvIn, EnvIn, _ValueOut). + eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- eval(C1, EnvIn, EnvTemp, _ValueOut), eval(C2, EnvTemp, EnvOut, ValueOut). @@ -117,6 +125,10 @@ eval(expr_term(T), EnvIn, EnvOut, ValueOut) :- eval(expr_assign(A), EnvIn, EnvOut, ValueOut) :- eval(A, EnvIn, EnvOut, ValueOut). +eval(term_exponent(Factor, Factor), EnvIn, Env2Out, ValueOut) :- + eval(Factor, EnvIn, Env1Out, Val1Out), + eval(Factor, Env1Out, Env2Out, Val2Out), + ValueOut is Val1Out ** Val2Out. eval(term_times(Factor, Term), EnvIn, Env2Out, ValueOut) :- eval(Factor, EnvIn, Env1Out, Val1Out), eval(Term, Env1Out, Env2Out, Val2Out), diff --git a/src/runtime/codeable_tests.pl b/src/runtime/codeable_tests.pl index d33876b..09e4f97 100644 --- a/src/runtime/codeable_tests.pl +++ b/src/runtime/codeable_tests.pl @@ -2,12 +2,24 @@ :- include("codeable.pl"). -test('`show 25` parses correctly') :- - program(P, [show, 25], []), - P = prog(show_numeric(25)). +test("show numeric parses correctly") :- + program(ParseTree, [show, 25], []), + ParseTree = prog(show_numeric(25)). -test('`show < hello world >` parses correctly') :- - program(P, [show, <, hello, world, >], []), - P = prog(show_string('hello world')). +test("show string parses correctly") :- + program(ParseTree, [show, <, hello, world, >], []), + ParseTree = prog(show_string('hello world')). + +test("assignment parses correctly") :- + assignment(ParseTree, [a, stores, -2], []), + ParseTree = assign(id(a), expr_term(term_factor(factor_numeric(-2)))). + +test("comments parse correctly") :- + comment(ParseTree, [fyi, <, this, is, a, comment, >], []), + ParseTree = fyi('this is a comment'). + +test("exponentiation parses correctly") :- + program(ParseTree, [a, stores, 2, raised-to, 3], []), + ParseTree = prog(assign(id(a), expr_term(term_exponent(factor_numeric(2), factor_numeric(3))))). :- end_tests(codeable). diff --git a/src/runtime/ide.js b/src/runtime/ide.js index dd3e497..48a6d45 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -86,21 +86,20 @@ function loadQuery(session) { var programText = document.getElementById("code").value; var tokens = tokenizer(programText); var formattedTokens = JSON.stringify(tokens).replaceAll('"', ""); - session.query( - `program(P, ${formattedTokens}, []), write(P), program_eval(P, 2, 3, Z).`, - { - success: function (goal) { - /* Goal parsed correctly */ - console.log("Successfully parsed query!"); - console.log(goal); - findAnswer(session); - }, - error: function (err) { - console.log("[ERROR] Failed to parse query"); - console.log(err); - }, - } - ); + var completeQuery = `program(P, ${formattedTokens}, []), write(P), program_eval(P, 2, 3, Z).`; + console.log(completeQuery); + session.query(completeQuery, { + success: function (goal) { + /* Goal parsed correctly */ + console.log("Successfully parsed query!"); + console.log(goal); + findAnswer(session); + }, + error: function (err) { + console.log("[ERROR] Failed to parse query"); + console.log(err); + }, + }); } function findAnswer(session) {