diff --git a/doc/grammar.md b/doc/grammar.md index 46fa033..5c8bddb 100644 --- a/doc/grammar.md +++ b/doc/grammar.md @@ -35,8 +35,8 @@ `string` := `identifier` `string` // Requirement 2 -`assignment` := `identifier` equals `expression` -`assignment_answer` := `identifier_answer` equals `expression` +`assignment` := `identifier` stores `expression` +`assignment_answer` := `identifier_answer` stores `expression` // Requirement 3a `ternary` := `expression` if `expression_boolean` otherwise `expression` @@ -56,7 +56,7 @@ // TODO - I'm thinking that "range(2,5)" could be a function that returns an iterable collection. That's how Python does it... // Requirement 5 -`print_statement` := show-value-of `identifier` +`print_statement` := show `identifier` // Other Features: Functions `argument` := `identifier` diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl new file mode 100644 index 0000000..4eb371c --- /dev/null +++ b/src/runtime/codeable.pl @@ -0,0 +1,239 @@ +% :- use_rendering(svgtree). % Only works in SWISH.swi-prolog.org + +/** + * codeable_version(-Major,-Minor,-Patch) is det. + */ +codeable_version(0,0,1). + +%%%%% Token Parser %%%%%% +% Parser - Numercis +number(t_number(N)) --> [N], {number(N)}. + +% v3 (Heavily inspired by M2.1 - slide 59) +% chars([X|Y]) --> char(X), chars(Y). +% chars([]) --> []. + +% char(X) --> [X], { is_char(X) }. + +% string(X) --> ['\"'], char(X), ['\"']. +% string(X) --> ['\"'], char(X), [' '], char(X), ['\"']. +% string(X) --> ['\"'], char(X), [' '], string(X), ['\"']. +identifier(id(A)) --> [a]. + +factor(factor_number(F)) --> number(F). +factor(factor_identifier(F)) --> identifier(F). +factor(factor_expression(F)) --> ['('], expr(F), [')']. + +term(term_factor(T)) --> factor(T). +term(term_times(T1, T2)) --> factor(T1), [times], term(T2). +term(term_divide(T1, T2)) --> factor(T1), [divided-by], term(T2). + +expr(expr_term(E)) --> term(E). +expr(expr_plus(E1, E2)) --> term(E1), [plus], expr(E2). +expr(expr_minus(E1, E2)) --> term(E1), [minus], expr(E2). +% expr(expr_ternary(T)) --> ternary(T). + +boolean(true) --> [true]. +boolean(false) --> [false]. +boolean(not(B)) --> [not], boolean(B). +boolean(equals(E1, E2)) --> expr(E1), [equals], expr(E2). +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). +loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. +loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. + +% show(show_char(C)) --> [show], char(C). +% show(show_string(S)) --> [show], string(S). +show(show_digit(D)) --> [show], digit(D). +show(show_identifier(I)) --> [show], identifier(I). + +command(C) --> assignment(C). +command(C) --> ternary(C). +command(C) --> loop(C). +command(C) --> show(C). +command(cmd(C1, C2)) --> assignment(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). + + +program(prog(P)) --> command(P). + +% Parser - Functions + +% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). + +% Functions eval + +% 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) + * + * Evaluates the parse tree rooted at Node, with the environment EnvIn, + * and returns the environment EnvOut and the value ValueOut. + * + * The environment is a list of pairs (Identifier, Value) where Identifier + * is a string and Value is an integer. + * + */ +eval(prog(P), EnvIn, EnvOut, ValueOut) :- + eval(P, EnvIn, EnvOut, ValueOut). + +eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- + eval(C1, EnvIn, EnvTemp, _ValueOut), + eval(C2, EnvTemp, EnvOut, ValueOut). + +eval(assign(I, E), EnvIn, EnvOut, ValueOut) :- + eval(E, EnvIn, EnvTemp, ValueOut), + update(I, ValueOut, EnvTemp, EnvOut). + +eval(if(B, T, _), EnvIn, EnvOut, ValueOut) :- + eval(B, EnvIn, EnvTemp, true), + eval(T, EnvTemp, EnvOut, ValueOut). +eval(if(B, _, F), EnvIn, EnvOut, ValueOut) :- + eval(B, EnvIn, EnvTemp, false), + eval(F, EnvTemp, EnvOut, ValueOut). + +eval(while(B, C), EnvIn, EnvOut, ValueOut) :- + eval(B, EnvIn, EnvTemp, true), + eval(C, EnvTemp, EnvTemp2, _ValueOut), + eval(while(B, C), EnvTemp2, EnvOut, ValueOut). +eval(while(B, _), EnvIn, EnvOut, _ValueOut) :- + eval(B, EnvIn, EnvOut, false). + +eval(expr_plus(Term, Expression), EnvIn, EnvOut, ValueOut) :- + eval(Term, EnvIn, EnvTemp, ValTerm), + eval(Expression, EnvTemp, EnvOut, ValExpr), + ValueOut is ValTerm + ValExpr. +eval(expr_minus(Term, Expression), EnvIn, EnvOut, ValueOut) :- + eval(Term, EnvIn, EnvTemp, ValTerm), + eval(Expression, EnvTemp, EnvOut, ValExpr), + ValueOut is ValTerm + (0 - ValExpr). +eval(expr_term(T), EnvIn, EnvOut, ValueOut) :- + eval(T, EnvIn, EnvOut, ValueOut). +eval(expr_assign(A), EnvIn, EnvOut, ValueOut) :- + eval(A, EnvIn, EnvOut, ValueOut). + +eval(term_times(Factor, Term), EnvIn, Env2Out, ValueOut) :- + eval(Factor, EnvIn, Env1Out, Val1Out), + eval(Term, Env1Out, Env2Out, Val2Out), + ValueOut is Val1Out * Val2Out. +eval(term_divide(Factor, Term), EnvIn, Env2Out, ValueOut) :- + eval(Factor, EnvIn, Env1Out, Val1Out), + eval(Term, Env1Out, Env2Out, Val2Out), + ValueOut is Val1Out * (1 / Val2Out). +eval(term_factor(F), EnvIn, EnvOut, ValueOut) :- + eval(F, EnvIn, EnvOut, ValueOut). + +eval(factor_digit(D), EnvIn, EnvIn, D). +eval(factor_identifier(I), EnvIn, EnvIn, Value) :- + lookup(I, EnvIn, Value). +eval(factor_expression(E), EnvIn, EnvOut, Value) :- + eval(E, EnvIn, EnvOut, Value). + +eval(true, EnvIn, EnvIn, true). +eval(false, EnvIn, EnvIn, false). +eval(not(B), EnvIn, EnvOut, false) :- + eval(B, EnvIn, EnvOut, true). +eval(not(B), EnvIn, EnvOut, true) :- + eval(B, EnvIn, EnvOut, false). +eval(equals(E1, E2), EnvIn, EnvOut, true) :- + eval(E1, EnvIn, EnvTemp, ValueOut), + eval(E2, EnvTemp, EnvOut, ValueOut). +eval(equals(E1, E2), EnvIn, EnvOut, false) :- + eval(E1, EnvIn, EnvTemp, ValueOut1), + eval(E2, EnvTemp, EnvOut, ValueOut2), + ValueOut1 =\= ValueOut2. + +eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). +eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). +eval(show_digit(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). +eval(show_identifier(I), EnvIn, EnvIn, _ValueOut) :- + lookup(I, EnvIn, Value), + write([output, Value]). + +/** + * lookup(+Identifier, +Env, -Value) + * + * Looks up the Value of Identifier in Env. + */ +lookup(Identifier, [(Identifier, Value) | _], Value). +lookup(Identifier, [(OtherIdentifier, _) | RemainingEnvironment], Value) :- + Identifier \= OtherIdentifier, + lookup(Identifier, RemainingEnvironment, Value). + +/** + * declare(+Identifier, +EnvIn, -EnvOut) + * + * Adds a new binding (Identifier, _) to EnvIn and returns EnvOut. + * + * If Identifier is already bound in EnvIn, it is not rebound. + */ +declare(Identifier, [], [(Identifier, _)]). +declare( + Identifier, + [(Identifier, Value) | RemainingEnvironment], + [(Identifier, Value) | RemainingEnvironment] +). +declare(Identifier, [H | RemainingEnvironment], [H | NewEnvironment]) :- + declare(Identifier, RemainingEnvironment, NewEnvironment). + +/** + * update(+Identifier, +Value, +EnvIn, -EnvOut) + * + * Updates the binding of Identifier in EnvIn to Value and returns EnvOut. + */ +update(Identifier, Value, [], [(Identifier, Value)]). +update( + Identifier, + Value, + [(Identifier, _) | RemainingEnvironment], + [(Identifier, Value) | RemainingEnvironment] +). +update( + Identifier, + Value, + [(OtherIdentifier, OtherValue) | RemainingEnvironment], + [(OtherIdentifier, OtherValue) | NewEnvironment] +) :- + Identifier \= OtherIdentifier, + update(Identifier, Value, RemainingEnvironment, NewEnvironment). + + +/** + * program_eval(+Program, +InitialX, +InitialY, -FinalZ) + * + * Evaluates the Program with the initial value of X and Y + * and returns the final value of Z. + */ +program_eval(P, X, Y, Z) :- + update(x, X, [], EnvX), + update(y, Y, EnvX, EnvY), + eval(P, EnvY, EnvOut, _ValueOut), + lookup(z, EnvOut, Z). + +digit(0) --> [0]. +digit(1) --> [1]. +digit(2) --> [2]. +digit(3) --> [3]. +digit(4) --> [4]. +digit(5) --> [5]. +digit(6) --> [6]. +digit(7) --> [7]. +digit(8) --> [8]. +digit(9) --> [9]. + +% identifier(WORD) --> { var(WORD), ! }, +% chars(CHARS), { atom_codes(WORD, CHARS) }. +% identifier(WORD) --> { nonvar(WORD) }, +% { atom_codes(WORD, CHARS) }, chars(CHARS). + +% is_char(X) :- X >= 0'a, X =< 0'z, !. +% is_char(X) :- X >= 0'A, X =< 0'Z, !. +% is_char(X) :- X >= 0'0, X =< 0'9, !. +% is_char(0'_). \ No newline at end of file diff --git a/src/runtime/ide.js b/src/runtime/ide.js index 3028df9..9fc35a2 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -2,7 +2,7 @@ let INTERPRETER_CODE_PATH = "jhaleAssign3.pl"; let intermediateCode = ""; function populateCodeArea() { - var sampleProgram = "begin\n\tvar z ; \n\tconst x = 3 ;\n\tz := x\nend ."; + var sampleProgram = "show 5"; var codeArea = document.getElementById("code"); codeArea.value = sampleProgram; } @@ -14,6 +14,11 @@ function hijackConsoleLog() { consoleLog("[DEBUG] Capturing intermediate code"); intermediateCode = message; } + if (message.toString().indexOf("output") == 1) { + consoleLog("[DEBUG] Capturing console output"); + let msg = message.toString().slice("[output,".length, -1); + document.getElementById("results").value = msg; + } consoleLog(message); }; } diff --git a/src/runtime/jhaleAssign3.pl b/src/runtime/jhaleAssign3.pl index 6cda847..4eb371c 100644 --- a/src/runtime/jhaleAssign3.pl +++ b/src/runtime/jhaleAssign3.pl @@ -1,71 +1,75 @@ % :- use_rendering(svgtree). % Only works in SWISH.swi-prolog.org + /** * codeable_version(-Major,-Minor,-Patch) is det. */ codeable_version(0,0,1). %%%%% Token Parser %%%%%% -digit(0) --> [0]. -digit(1) --> [1]. -digit(2) --> [2]. -digit(3) --> [3]. -digit(4) --> [4]. -digit(5) --> [5]. -digit(6) --> [6]. -digit(7) --> [7]. -digit(8) --> [8]. -digit(9) --> [9]. - -identifier(x) --> [x]. -identifier(y) --> [y]. -identifier(z) --> [z]. -identifier(u) --> [u]. -identifier(v) --> [v]. +% Parser - Numercis +number(t_number(N)) --> [N], {number(N)}. % v3 (Heavily inspired by M2.1 - slide 59) -factor(factor_digit(F)) --> digit(F). +% chars([X|Y]) --> char(X), chars(Y). +% chars([]) --> []. + +% char(X) --> [X], { is_char(X) }. + +% string(X) --> ['\"'], char(X), ['\"']. +% string(X) --> ['\"'], char(X), [' '], char(X), ['\"']. +% string(X) --> ['\"'], char(X), [' '], string(X), ['\"']. +identifier(id(A)) --> [a]. + +factor(factor_number(F)) --> number(F). factor(factor_identifier(F)) --> identifier(F). factor(factor_expression(F)) --> ['('], expr(F), [')']. term(term_factor(T)) --> factor(T). -term(term_times(T1, T2)) --> factor(T1), [*], term(T2). -term(term_divide(T1, T2)) --> factor(T1), [/], term(T2). +term(term_times(T1, T2)) --> factor(T1), [times], term(T2). +term(term_divide(T1, T2)) --> factor(T1), [divided-by], term(T2). expr(expr_term(E)) --> term(E). -expr(expr_plus(E1, E2)) --> term(E1), [+], expr(E2). -expr(expr_minus(E1, E2)) --> term(E1), [-], expr(E2). -expr(expr_assign(A)) --> assignment(A). +expr(expr_plus(E1, E2)) --> term(E1), [plus], expr(E2). +expr(expr_minus(E1, E2)) --> term(E1), [minus], expr(E2). +% expr(expr_ternary(T)) --> ternary(T). boolean(true) --> [true]. boolean(false) --> [false]. boolean(not(B)) --> [not], boolean(B). -boolean(equals(E1, E2)) --> expr(E1), [=], expr(E2). +boolean(equals(E1, E2)) --> expr(E1), [equals], expr(E2). +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), [:=], expr(E). -ternary(if(B, T, F)) --> [if], boolean(B), [then], command(T), [else], command(F), [endif]. -loop(while(B, C)) --> [while], boolean(B), [do], command(C), [endwhile]. +assignment(assign(I, E)) --> identifier(I), [stores], expr(E). +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]. + +% show(show_char(C)) --> [show], char(C). +% show(show_string(S)) --> [show], string(S). +show(show_digit(D)) --> [show], digit(D). +show(show_identifier(I)) --> [show], identifier(I). command(C) --> assignment(C). command(C) --> ternary(C). command(C) --> loop(C). -command(C) --> block(C). +command(C) --> show(C). command(cmd(C1, C2)) --> assignment(C1), [;], command(C2). command(cmd(C1, C2)) --> ternary(C1), [;], command(C2). command(cmd(C1, C2)) --> loop(C1), [;], command(C2). -command(cmd(C1, C2)) --> block(C1), [;], command(C2). +command(cmd(C1, C2)) --> show(C1), [;], command(C2). + -constant(const(I, N)) --> [const], identifier(I), [=], digit(N). -variable(var(I)) --> [var], identifier(I). +program(prog(P)) --> command(P). -declaration(D) --> constant(D). -declaration(D) --> variable(D). -declaration(decl(D1, D2)) --> constant(D1), [;], declaration(D2). -declaration(decl(D1, D2)) --> variable(D1), [;], declaration(D2). +% Parser - Functions -block(blk(D, C)) --> [begin], declaration(D), [;], command(C), [end]. +% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). -program(prog(P)) --> block(P), ['.']. +% Functions eval +% 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) @@ -80,18 +84,6 @@ program(prog(P)) --> block(P), ['.']. eval(prog(P), EnvIn, EnvOut, ValueOut) :- eval(P, EnvIn, EnvOut, ValueOut). -eval(blk(D, C), EnvIn, EnvOut, ValueOut) :- - eval(D, EnvIn, EnvDecl, _ValueOut), - eval(C, EnvDecl, EnvOut, ValueOut). - -eval(var(I), EnvIn, EnvOut, _) :- - declare(I, EnvIn, EnvOut). -eval(const(I, N), EnvIn, EnvOut, N) :- - update(I, N, EnvIn, EnvOut). -eval(decl(D1, D2), EnvIn, EnvOut, ValueOut) :- - eval(D1, EnvIn, EnvTemp, _ValueOut), - eval(D2, EnvTemp, EnvOut, ValueOut). - eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- eval(C1, EnvIn, EnvTemp, _ValueOut), eval(C2, EnvTemp, EnvOut, ValueOut). @@ -158,6 +150,13 @@ eval(equals(E1, E2), EnvIn, EnvOut, false) :- eval(E2, EnvTemp, EnvOut, ValueOut2), ValueOut1 =\= ValueOut2. +eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). +eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). +eval(show_digit(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). +eval(show_identifier(I), EnvIn, EnvIn, _ValueOut) :- + lookup(I, EnvIn, Value), + write([output, Value]). + /** * lookup(+Identifier, +Env, -Value) * @@ -217,3 +216,24 @@ program_eval(P, X, Y, Z) :- update(y, Y, EnvX, EnvY), eval(P, EnvY, EnvOut, _ValueOut), lookup(z, EnvOut, Z). + +digit(0) --> [0]. +digit(1) --> [1]. +digit(2) --> [2]. +digit(3) --> [3]. +digit(4) --> [4]. +digit(5) --> [5]. +digit(6) --> [6]. +digit(7) --> [7]. +digit(8) --> [8]. +digit(9) --> [9]. + +% identifier(WORD) --> { var(WORD), ! }, +% chars(CHARS), { atom_codes(WORD, CHARS) }. +% identifier(WORD) --> { nonvar(WORD) }, +% { atom_codes(WORD, CHARS) }, chars(CHARS). + +% is_char(X) :- X >= 0'a, X =< 0'z, !. +% is_char(X) :- X >= 0'A, X =< 0'Z, !. +% is_char(X) :- X >= 0'0, X =< 0'9, !. +% is_char(0'_). \ No newline at end of file diff --git a/src/runtime/tokenizer.js b/src/runtime/tokenizer.js deleted file mode 100644 index 7658c02..0000000 --- a/src/runtime/tokenizer.js +++ /dev/null @@ -1,8 +0,0 @@ -function tokenizer(fulltext) -{ - var tokens = fulltext.split(" "); - debugger - return tokens; -} - -module.exports = tokenizer; \ No newline at end of file -- knotmirror 0.0.1 From 96f4d83d6f91573993dddee59301300cb127a1a1 Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 13:22:16 -0700 Subject: [PATCH 02/24] Implement Strings Co-authored-by: Rithvik Arun Co-authored-by: jgjanes --- doc/grammar.md | 5 +++-- src/runtime/codeable.pl | 24 +++++++++++------------- src/runtime/codeable_tests.pl | 13 +++++++++++++ src/runtime/ide.html | 11 ----------- src/runtime/ide.js | 9 +++++---- 5 files changed, 32 insertions(+), 30 deletions(-) create mode 100644 src/runtime/codeable_tests.pl diff --git a/doc/grammar.md b/doc/grammar.md index 5c8bddb..a9452dc 100644 --- a/doc/grammar.md +++ b/doc/grammar.md @@ -31,8 +31,9 @@ `expression` := `expression` divided-by `expression` // Requirement 1c -`string` := `identifier` -`string` := `identifier` `string` +`word` := `identifier` +`word` := `identifier` `word` +`string` := < `word` > // Requirement 2 `assignment` := `identifier` stores `expression` diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 4eb371c..ef08074 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -7,20 +7,20 @@ codeable_version(0,0,1). %%%%% Token Parser %%%%%% % Parser - Numercis -number(t_number(N)) --> [N], {number(N)}. +numeric(N) --> [N], {number(N)}. % v3 (Heavily inspired by M2.1 - slide 59) % chars([X|Y]) --> char(X), chars(Y). % chars([]) --> []. -% char(X) --> [X], { is_char(X) }. +char(C) --> [C], { char_type(C, alpha) }. -% string(X) --> ['\"'], char(X), ['\"']. -% string(X) --> ['\"'], char(X), [' '], char(X), ['\"']. -% string(X) --> ['\"'], char(X), [' '], string(X), ['\"']. +word([A]) --> [A], {atom(A)}. +word([A1 | A2]) --> [A1], word(A2), {atom(A1)}. +strings(S) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. identifier(id(A)) --> [a]. -factor(factor_number(F)) --> number(F). +factor(factor_numeric(F)) --> numeric(F). factor(factor_identifier(F)) --> identifier(F). factor(factor_expression(F)) --> ['('], expr(F), [')']. @@ -45,9 +45,8 @@ 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]. -% show(show_char(C)) --> [show], char(C). -% show(show_string(S)) --> [show], string(S). -show(show_digit(D)) --> [show], digit(D). +show(show_string(S)) --> [show], strings(S). +show(show_numeric(D)) --> [show], numeric(D). show(show_identifier(I)) --> [show], identifier(I). command(C) --> assignment(C). @@ -59,7 +58,6 @@ command(cmd(C1, C2)) --> ternary(C1), [;], command(C2). command(cmd(C1, C2)) --> loop(C1), [;], command(C2). command(cmd(C1, C2)) --> show(C1), [;], command(C2). - program(prog(P)) --> command(P). % Parser - Functions @@ -152,7 +150,7 @@ eval(equals(E1, E2), EnvIn, EnvOut, false) :- eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). -eval(show_digit(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). +eval(show_numeric(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). eval(show_identifier(I), EnvIn, EnvIn, _ValueOut) :- lookup(I, EnvIn, Value), write([output, Value]). @@ -229,9 +227,9 @@ digit(8) --> [8]. digit(9) --> [9]. % identifier(WORD) --> { var(WORD), ! }, -% chars(CHARS), { atom_codes(WORD, CHARS) }. +% chars(CHARS), { atom_codes(WORD, CHARS) }. % identifier(WORD) --> { nonvar(WORD) }, -% { atom_codes(WORD, CHARS) }, chars(CHARS). +% { atom_codes(WORD, CHARS) }, chars(CHARS). % is_char(X) :- X >= 0'a, X =< 0'z, !. % is_char(X) :- X >= 0'A, X =< 0'Z, !. diff --git a/src/runtime/codeable_tests.pl b/src/runtime/codeable_tests.pl new file mode 100644 index 0000000..d33876b --- /dev/null +++ b/src/runtime/codeable_tests.pl @@ -0,0 +1,13 @@ +:- begin_tests(codeable). +:- include("codeable.pl"). + + +test('`show 25` parses correctly') :- + program(P, [show, 25], []), + P = prog(show_numeric(25)). + +test('`show < hello world >` parses correctly') :- + program(P, [show, <, hello, world, >], []), + P = prog(show_string('hello world')). + +:- end_tests(codeable). diff --git a/src/runtime/ide.html b/src/runtime/ide.html index d00d217..1b33998 100644 --- a/src/runtime/ide.html +++ b/src/runtime/ide.html @@ -2,17 +2,6 @@ - - diff --git a/src/runtime/ide.js b/src/runtime/ide.js index 9fc35a2..dd3e497 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -1,8 +1,8 @@ -let INTERPRETER_CODE_PATH = "jhaleAssign3.pl"; +let INTERPRETER_CODE_PATH = "codeable.pl"; let intermediateCode = ""; function populateCodeArea() { - var sampleProgram = "show 5"; + var sampleProgram = "show 25"; var codeArea = document.getElementById("code"); codeArea.value = sampleProgram; } @@ -51,7 +51,8 @@ function patchIntermediateCode(session) { success: (answer) => { var patchedCode = intermediateCode .replace("[(|", "['('|") - .replace("[)|", "[')'|"); + .replace("[)|", "[')'|") + .replace(", ,", ",' ',"); console.log(patchedCode); }, error: (err) => { @@ -107,7 +108,7 @@ function findAnswer(session) { session.answer({ success: function (answer) { document.getElementById("results").value = session.format_answer(answer); - console.log(session.format_answer(answer)); // {X/apple} + console.log(answer); // {X/apple} }, error: function (err) { /* Uncaught error */ -- knotmirror 0.0.1 From 5f1a9198ccbda499fda4684a479fcf85581f66f7 Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 14:47:19 -0700 Subject: [PATCH 03/24] WIP Codeable Improvements Adding some unit tests and new language features. Co-authored-by: Rithvik Arun Co-authored-by: jgjanes --- data/quadratic_formula.md | 26 ++++++++++++++++---------- src/runtime/codeable.pl | 32 ++++++++++++++++++++++---------- src/runtime/codeable_tests.pl | 24 ++++++++++++++++++------ src/runtime/ide.js | 29 ++++++++++++++--------------- 4 files changed, 70 insertions(+), 41 deletions(-) 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) { -- knotmirror 0.0.1 From 236162209d5135ae7d88a415a530bc7662198aff Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 16:42:36 -0700 Subject: [PATCH 04/24] Successfully evaluate `quadratic formula`! Co-authored-by: jgjanes Co-authored-by: Rithvik Arun Co-authored-by: Jacob Hreshchyshyn Co-authored-by: Sai Nishanth Vaka --- data/fibanocci.md | 4 +-- data/quadratic_formula.md | 18 ++++++------- src/runtime/codeable.pl | 54 +++++++++++++++++++-------------------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/data/fibanocci.md b/data/fibanocci.md index 095e8d1..69a4829 100644 --- a/data/fibanocci.md +++ b/data/fibanocci.md @@ -1,12 +1,12 @@ fibonacci needs n value equals 1 -if n is-greater-than 1 +if n is_greater_than 1 temp_1 equals subtraction of n with 1 temp_2 equals subtraction of n with 2 value_1 equals fibonacci of temp_1 value_2 equals fibonacci of temp_2 value equals addition of value1 with value2 -move-on +move_on answer equals value fyi example of recursion \ No newline at end of file diff --git a/data/quadratic_formula.md b/data/quadratic_formula.md index 3a16434..afdc29e 100644 --- a/data/quadratic_formula.md +++ b/data/quadratic_formula.md @@ -3,14 +3,14 @@ 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 +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 +root stores numerator divided_by denominator -show root \ No newline at end of file +show root diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 16d9e70..15fd039 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -12,9 +12,9 @@ numeric(N) --> [N], {number(N)}. % v3 (Heavily inspired by M2.1 - slide 59) char(C) --> [C], { char_type(C, alpha) }. -identifier(id(I)) --> [I], {atom(I)}. +identifier(I) --> [I], {atom(I)}. -word([W]) --> identifier(id(W)). +word([W]) --> identifier(W). word([W1 | W2]) --> [W1], word(W2), {atom(W1)}. strings(S) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. @@ -25,11 +25,11 @@ factor(factor_identifier(F)) --> identifier(F). factor(factor_expression(F)) --> ['('], expr(F), [')']. sub_term(term_factor(T)) --> factor(T). -sub_term(term_exponent(F1, F2)) --> factor(F1), [raised-to], factor(F2). +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). +term(term_divide(T1, T2)) --> factor(T1), [divided_by], term(T2). expr(expr_term(E)) --> term(E). expr(expr_plus(E1, E2)) --> term(E1), [plus], expr(E2). @@ -40,8 +40,8 @@ boolean(true) --> [true]. boolean(false) --> [false]. boolean(not(B)) --> [not], boolean(B). boolean(equals(E1, E2)) --> expr(E1), [equals], expr(E2). -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). +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). @@ -52,16 +52,16 @@ show(show_string(S)) --> [show], strings(S). show(show_numeric(D)) --> [show], numeric(D). show(show_identifier(I)) --> [show], identifier(I). +command(cmd(C1, C2)) --> comment(C1), command(C2). +command(cmd(C1, C2)) --> assignment(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(C) --> comment(C). command(C) --> assignment(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)) --> 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). @@ -88,7 +88,7 @@ program(prog(P)) --> command(P). eval(prog(P), EnvIn, EnvOut, ValueOut) :- eval(P, EnvIn, EnvOut, ValueOut). -eval(fyi(S), EnvIn, EnvIn, _ValueOut). +eval(fyi(_S), EnvIn, EnvIn, _ValueOut). eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- eval(C1, EnvIn, EnvTemp, _ValueOut), @@ -125,9 +125,9 @@ 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), +eval(term_exponent(Factor1, Factor2), EnvIn, Env2Out, ValueOut) :- + eval(Factor1, EnvIn, Env1Out, Val1Out), + eval(Factor2, Env1Out, Env2Out, Val2Out), ValueOut is Val1Out ** Val2Out. eval(term_times(Factor, Term), EnvIn, Env2Out, ValueOut) :- eval(Factor, EnvIn, Env1Out, Val1Out), @@ -140,7 +140,7 @@ eval(term_divide(Factor, Term), EnvIn, Env2Out, ValueOut) :- eval(term_factor(F), EnvIn, EnvOut, ValueOut) :- eval(F, EnvIn, EnvOut, ValueOut). -eval(factor_digit(D), EnvIn, EnvIn, D). +eval(factor_numeric(D), EnvIn, EnvIn, D). eval(factor_identifier(I), EnvIn, EnvIn, Value) :- lookup(I, EnvIn, Value). eval(factor_expression(E), EnvIn, EnvOut, Value) :- @@ -227,16 +227,16 @@ program_eval(P, X, Y, Z) :- eval(P, EnvY, EnvOut, _ValueOut), lookup(z, EnvOut, Z). -digit(0) --> [0]. -digit(1) --> [1]. -digit(2) --> [2]. -digit(3) --> [3]. -digit(4) --> [4]. -digit(5) --> [5]. -digit(6) --> [6]. -digit(7) --> [7]. -digit(8) --> [8]. -digit(9) --> [9]. +% digit(0) --> [0]. +% digit(1) --> [1]. +% digit(2) --> [2]. +% digit(3) --> [3]. +% digit(4) --> [4]. +% digit(5) --> [5]. +% digit(6) --> [6]. +% digit(7) --> [7]. +% digit(8) --> [8]. +% digit(9) --> [9]. % identifier(WORD) --> { var(WORD), ! }, % chars(CHARS), { atom_codes(WORD, CHARS) }. -- knotmirror 0.0.1 From 34db1f9d863734d5356fddf3c61e17a8b28c04f8 Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 16:44:21 -0700 Subject: [PATCH 05/24] Cleanup dead code --- src/Codeable_Eval_Parser.pl | 248 ------------------------------------ src/parser_eval.pl | 36 ------ src/runtime/codeable.pl | 27 +--- 3 files changed, 5 insertions(+), 306 deletions(-) delete mode 100644 src/Codeable_Eval_Parser.pl delete mode 100644 src/parser_eval.pl diff --git a/src/Codeable_Eval_Parser.pl b/src/Codeable_Eval_Parser.pl deleted file mode 100644 index 7971db2..0000000 --- a/src/Codeable_Eval_Parser.pl +++ /dev/null @@ -1,248 +0,0 @@ -% :- use_rendering(svgtree). % Only works in SWISH.swi-prolog.org - - -%%%%% Token Parser %%%%%% - -% Parser - Numercis -number(t_number(N)) --> [N], {number(N)}. - -% v3 (Heavily inspired by M2.1 - slide 59) -chars([X|Y]) --> char(X), chars(Y). -chars([]) --> []. - -char(X) --> [X], { is_char(X) }. - -string(X) --> ['\"'], char(X), ['\"']. -string(X) --> ['\"'], char(X), [' '], char(X), ['\"']. -string(X) --> ['\"'], char(X), [' '], string(X), ['\"']. - -factor(factor_number(F)) --> number(F). -factor(factor_identifier(F)) --> identifier(F). -factor(factor_expression(F)) --> ['('], expr(F), [')']. - -term(term_factor(T)) --> factor(T). -term(term_times(T1, T2)) --> [multiplication],[of], factor(T1), [with], term(T2). -term(term_divide(T1, T2)) --> [division],[of], factor(T1), [with], term(T2). - -expr(expr_term(E)) --> term(E). -expr(expr_plus(E1, E2)) --> [addition], [of], term(E1), [with], expr(E2). -expr(expr_minus(E1, E2)) --> [subtraction], [of], term(E1), [with], expr(E2). -expr(expr_assign(A)) --> assignment(A). - -boolean(true) --> [true]. -boolean(false) --> [false]. -boolean(not(B)) --> [not], boolean(B). -boolean(equals(E1, E2)) --> expr(E1), [is-equal-to], expr(E2). -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), [equals], expr(E). -ternary(if(B, T, F)) --> [if], boolean(B), [then], command(T), [else], command(F), [endif]. -loop(while(B, C)) --> [while], boolean(B), command(C), [endwathile]. -loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. - -printC(print_char(C)) --> [printC], char(C). -printC(print_string(S)) --> [printC], string(S). -printC(print_digit(D)) --> [printC], digit(D). - -command(C) --> assignment(C). -command(C) --> ternary(C). -command(C) --> loop(C). -command(C) --> block(C). -command(cmd(C1, C2)) --> assignment(C1), [;], command(C2). -command(cmd(C1, C2)) --> ternary(C1), [;], command(C2). -command(cmd(C1, C2)) --> loop(C1), [;], command(C2). -command(cmd(C1, C2)) --> block(C1), [;], command(C2). - -constant(const(I, N)) --> [const], identifier(I), [=], digit(N). -variable(var(I)) --> [var], identifier(I). - -declaration(D) --> constant(D). -declaration(D) --> variable(D). -declaration(decl(D1, D2)) --> constant(D1), [;], declaration(D2). -declaration(decl(D1, D2)) --> variable(D1), [;], declaration(D2). - -block(blk(D, C)) --> [begin], declaration(D), [;], command(C), [end]. - -program(prog(P)) --> block(P), ['.']. - -% Parser - Functions - -functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). - -% Functions eval - -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) - * - * Evaluates the parse tree rooted at Node, with the environment EnvIn, - * and returns the environment EnvOut and the value ValueOut. - * - * The environment is a list of pairs (Identifier, Value) where Identifier - * is a string and Value is an integer. - * - */ -eval(prog(P), EnvIn, EnvOut, ValueOut) :- - eval(P, EnvIn, EnvOut, ValueOut). - -eval(blk(D, C), EnvIn, EnvOut, ValueOut) :- - eval(D, EnvIn, EnvDecl, _ValueOut), - eval(C, EnvDecl, EnvOut, ValueOut). - -eval(var(I), EnvIn, EnvOut, _) :- - declare(I, EnvIn, EnvOut). -eval(const(I, N), EnvIn, EnvOut, N) :- - update(I, N, EnvIn, EnvOut). -eval(decl(D1, D2), EnvIn, EnvOut, ValueOut) :- - eval(D1, EnvIn, EnvTemp, _ValueOut), - eval(D2, EnvTemp, EnvOut, ValueOut). - -eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- - eval(C1, EnvIn, EnvTemp, _ValueOut), - eval(C2, EnvTemp, EnvOut, ValueOut). - -eval(assign(I, E), EnvIn, EnvOut, ValueOut) :- - eval(E, EnvIn, EnvTemp, ValueOut), - update(I, ValueOut, EnvTemp, EnvOut). - -eval(if(B, T, _), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, true), - eval(T, EnvTemp, EnvOut, ValueOut). -eval(if(B, _, F), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, false), - eval(F, EnvTemp, EnvOut, ValueOut). - -eval(while(B, C), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, true), - eval(C, EnvTemp, EnvTemp2, _ValueOut), - eval(while(B, C), EnvTemp2, EnvOut, ValueOut). -eval(while(B, _), EnvIn, EnvOut, _ValueOut) :- - eval(B, EnvIn, EnvOut, false). - -eval(expr_plus(Term, Expression), EnvIn, EnvOut, ValueOut) :- - eval(Term, EnvIn, EnvTemp, ValTerm), - eval(Expression, EnvTemp, EnvOut, ValExpr), - ValueOut is ValTerm + ValExpr. -eval(expr_minus(Term, Expression), EnvIn, EnvOut, ValueOut) :- - eval(Term, EnvIn, EnvTemp, ValTerm), - eval(Expression, EnvTemp, EnvOut, ValExpr), - ValueOut is ValTerm + (0 - ValExpr). -eval(expr_term(T), EnvIn, EnvOut, ValueOut) :- - eval(T, EnvIn, EnvOut, ValueOut). -eval(expr_assign(A), EnvIn, EnvOut, ValueOut) :- - eval(A, EnvIn, EnvOut, ValueOut). - -eval(term_times(Factor, Term), EnvIn, Env2Out, ValueOut) :- - eval(Factor, EnvIn, Env1Out, Val1Out), - eval(Term, Env1Out, Env2Out, Val2Out), - ValueOut is Val1Out * Val2Out. -eval(term_divide(Factor, Term), EnvIn, Env2Out, ValueOut) :- - eval(Factor, EnvIn, Env1Out, Val1Out), - eval(Term, Env1Out, Env2Out, Val2Out), - ValueOut is Val1Out * (1 / Val2Out). -eval(term_factor(F), EnvIn, EnvOut, ValueOut) :- - eval(F, EnvIn, EnvOut, ValueOut). - -eval(factor_digit(D), EnvIn, EnvIn, D). -eval(factor_identifier(I), EnvIn, EnvIn, Value) :- - lookup(I, EnvIn, Value). -eval(factor_expression(E), EnvIn, EnvOut, Value) :- - eval(E, EnvIn, EnvOut, Value). - -eval(true, EnvIn, EnvIn, true). -eval(false, EnvIn, EnvIn, false). -eval(not(B), EnvIn, EnvOut, false) :- - eval(B, EnvIn, EnvOut, true). -eval(not(B), EnvIn, EnvOut, true) :- - eval(B, EnvIn, EnvOut, false). -eval(equals(E1, E2), EnvIn, EnvOut, true) :- - eval(E1, EnvIn, EnvTemp, ValueOut), - eval(E2, EnvTemp, EnvOut, ValueOut). -eval(equals(E1, E2), EnvIn, EnvOut, false) :- - eval(E1, EnvIn, EnvTemp, ValueOut1), - eval(E2, EnvTemp, EnvOut, ValueOut2), - ValueOut1 =\= ValueOut2. - -/** - * lookup(+Identifier, +Env, -Value) - * - * Looks up the Value of Identifier in Env. - */ -lookup(Identifier, [(Identifier, Value) | _], Value). -lookup(Identifier, [(OtherIdentifier, _) | RemainingEnvironment], Value) :- - Identifier \= OtherIdentifier, - lookup(Identifier, RemainingEnvironment, Value). - -/** - * declare(+Identifier, +EnvIn, -EnvOut) - * - * Adds a new binding (Identifier, _) to EnvIn and returns EnvOut. - * - * If Identifier is already bound in EnvIn, it is not rebound. - */ -declare(Identifier, [], [(Identifier, _)]). -declare( - Identifier, - [(Identifier, Value) | RemainingEnvironment], - [(Identifier, Value) | RemainingEnvironment] -). -declare(Identifier, [H | RemainingEnvironment], [H | NewEnvironment]) :- - declare(Identifier, RemainingEnvironment, NewEnvironment). - -/** - * update(+Identifier, +Value, +EnvIn, -EnvOut) - * - * Updates the binding of Identifier in EnvIn to Value and returns EnvOut. - */ -update(Identifier, Value, [], [(Identifier, Value)]). -update( - Identifier, - Value, - [(Identifier, _) | RemainingEnvironment], - [(Identifier, Value) | RemainingEnvironment] -). -update( - Identifier, - Value, - [(OtherIdentifier, OtherValue) | RemainingEnvironment], - [(OtherIdentifier, OtherValue) | NewEnvironment] -) :- - Identifier \= OtherIdentifier, - update(Identifier, Value, RemainingEnvironment, NewEnvironment). - - -/** - * program_eval(+Program, +InitialX, +InitialY, -FinalZ) - * - * Evaluates the Program with the initial value of X and Y - * and returns the final value of Z. - */ -program_eval(P, X, Y, Z) :- - update(x, X, [], EnvX), - update(y, Y, EnvX, EnvY), - eval(P, EnvY, EnvOut, _ValueOut), - lookup(z, EnvOut, Z). - -digit(0) --> [0]. -digit(1) --> [1]. -digit(2) --> [2]. -digit(3) --> [3]. -digit(4) --> [4]. -digit(5) --> [5]. -digit(6) --> [6]. -digit(7) --> [7]. -digit(8) --> [8]. -digit(9) --> [9]. - -identifier(WORD) --> { var(WORD), ! }, - chars(CHARS), { atom_codes(WORD, CHARS) }. -identifier(WORD) --> { nonvar(WORD) }, - { atom_codes(WORD, CHARS) }, chars(CHARS). - -is_char(X) :- X >= 0'a, X =< 0'z, !. -is_char(X) :- X >= 0'A, X =< 0'Z, !. -is_char(X) :- X >= 0'0, X =< 0'9, !. -is_char(0'_). \ No newline at end of file diff --git a/src/parser_eval.pl b/src/parser_eval.pl deleted file mode 100644 index 097ed50..0000000 --- a/src/parser_eval.pl +++ /dev/null @@ -1,36 +0,0 @@ -% Language: Codeable -% Authors: Jacob H, Jacob J, Joseph H, Rithvik A, Sai Nishanth V. -% Version: 0.5.20220423 - - -% Main Parser -codeable(t_codeable(X)). - -% Parser - Numercis -number(t_number(N)) --> [N], {number(N)}. - -% Parser - Booleans -% boolean -boolean(t_bool_true) --> [true]. -boolean(t_bool_false) --> [false]. - -% Boolean comparission -bool_expr(t_is_equal_to(X,Y)) --> expression(X), [is-equal-to], expression(Y). - - -% Parser - Assignment -expression(t_assign_exprmult(X,Y)) --> id(X), [equals], expression(Y). -expression(X) --> expr(X). - -% Parser - Functions - -functions(t_functions(A,X,Y)) --> [begin], decl(X), [;], comm(Y), [end]. - -% Functions eval - -function_eval(Id, Args, [(Id,t_codeable_functions(Pt))|_],Value). -function_eval(Id, Aegs, [_|T],Value) :- function_eval(Id, T, Value). - - -% Main evaluator -codeable_evaluator(t_codeable(Pt), R). \ No newline at end of file diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 15fd039..eae7071 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -69,6 +69,10 @@ program(prog(P)) --> command(P). % functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). +% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). +% decl_al([]) --> []. +% decl_al([H|T]) --> identifier(H), decl_al(T). + % Functions eval % function_eval(Id, Args, [(Id,t_codeable_functions(Pt))|_],Value). @@ -225,25 +229,4 @@ program_eval(P, X, Y, Z) :- update(x, X, [], EnvX), update(y, Y, EnvX, EnvY), eval(P, EnvY, EnvOut, _ValueOut), - lookup(z, EnvOut, Z). - -% digit(0) --> [0]. -% digit(1) --> [1]. -% digit(2) --> [2]. -% digit(3) --> [3]. -% digit(4) --> [4]. -% digit(5) --> [5]. -% digit(6) --> [6]. -% digit(7) --> [7]. -% digit(8) --> [8]. -% digit(9) --> [9]. - -% identifier(WORD) --> { var(WORD), ! }, -% chars(CHARS), { atom_codes(WORD, CHARS) }. -% identifier(WORD) --> { nonvar(WORD) }, -% { atom_codes(WORD, CHARS) }, chars(CHARS). - -% is_char(X) :- X >= 0'a, X =< 0'z, !. -% is_char(X) :- X >= 0'A, X =< 0'Z, !. -% is_char(X) :- X >= 0'0, X =< 0'9, !. -% is_char(0'_). \ No newline at end of file + lookup(z, EnvOut, Z). \ No newline at end of file -- knotmirror 0.0.1 From 89d113d61f32639a61209639e51b4c49dce20d82 Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 17:00:21 -0700 Subject: [PATCH 06/24] Successfully evaluate `factorial`! Co-authored-by: jgjanes Co-authored-by: Rithvik Arun Co-authored-by: Sai Nishanth Vaka --- data/factorial.md | 24 ++++++++++++++---------- src/runtime/codeable.pl | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/data/factorial.md b/data/factorial.md index d400eb0..7eec0d5 100644 --- a/data/factorial.md +++ b/data/factorial.md @@ -1,12 +1,16 @@ -factorial needs n -value equals 1 -temp equals n -while temp is-greater-than 1 -temp2 equals value -value equals multiplication of temp with temp2 -temp3 equals temp -temp equals substraction of temp3 with 1 +fyi < factorial > +fyi < example of while loop block > + +n stores 4 + +value stores 1 +temp stores n + +while temp is_greater_than 1 + temp2 stores value + value stores temp times temp2 + temp3 stores temp + temp stores temp3 minus 1 repeat -answer equals value -fyi fyi example of while loop block \ No newline at end of file +show value diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index eae7071..31abcc3 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -15,7 +15,7 @@ char(C) --> [C], { char_type(C, alpha) }. identifier(I) --> [I], {atom(I)}. word([W]) --> identifier(W). -word([W1 | W2]) --> [W1], word(W2), {atom(W1)}. +word([W1 | W2]) --> [W1], word(W2), { atom(W1), W1 \= <, W1 \= > }. strings(S) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. comment(fyi(S)) --> [fyi], strings(S). @@ -163,6 +163,22 @@ eval(equals(E1, E2), EnvIn, EnvOut, false) :- eval(E1, EnvIn, EnvTemp, ValueOut1), eval(E2, EnvTemp, EnvOut, ValueOut2), ValueOut1 =\= ValueOut2. +eval(is_less_than(E1, E2), EnvIn, EnvOut, true) :- + eval(E1, EnvIn, EnvTemp, ValueOut1), + eval(E2, EnvTemp, EnvOut, ValueOut2), + ValueOut1 < ValueOut2. +eval(is_less_than(E1, E2), EnvIn, EnvOut, false) :- + eval(E1, EnvIn, EnvTemp, ValueOut1), + eval(E2, EnvTemp, EnvOut, ValueOut2), + ValueOut1 >= ValueOut2. +eval(is_greater_than(E1, E2), EnvIn, EnvOut, true) :- + eval(E1, EnvIn, EnvTemp, ValueOut1), + eval(E2, EnvTemp, EnvOut, ValueOut2), + ValueOut1 > ValueOut2. +eval(is_greater_than(E1, E2), EnvIn, EnvOut, false) :- + eval(E1, EnvIn, EnvTemp, ValueOut1), + eval(E2, EnvTemp, EnvOut, ValueOut2), + ValueOut1 =< ValueOut2. eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). -- knotmirror 0.0.1 From a7cb492672cb0e46975f609355d356450ba7f67d Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 17:35:33 -0700 Subject: [PATCH 07/24] Successfully evaluate `fibonacci`! --- data/fibanocci.md | 12 ------------ data/fibonacci.md | 30 ++++++++++++++++++++++++++++++ src/runtime/codeable.pl | 11 ++++++++++- 3 files changed, 40 insertions(+), 13 deletions(-) delete mode 100644 data/fibanocci.md create mode 100644 data/fibonacci.md diff --git a/data/fibanocci.md b/data/fibanocci.md deleted file mode 100644 index 69a4829..0000000 --- a/data/fibanocci.md +++ /dev/null @@ -1,12 +0,0 @@ -fibonacci needs n -value equals 1 -if n is_greater_than 1 -temp_1 equals subtraction of n with 1 -temp_2 equals subtraction of n with 2 -value_1 equals fibonacci of temp_1 -value_2 equals fibonacci of temp_2 -value equals addition of value1 with value2 -move_on -answer equals value - -fyi example of recursion \ No newline at end of file diff --git a/data/fibonacci.md b/data/fibonacci.md new file mode 100644 index 0000000..9f24f85 --- /dev/null +++ b/data/fibonacci.md @@ -0,0 +1,30 @@ +fyi < fibonacci > +fyi < example of if statements > + +n stores 8 + +fib stores n if n is_less_than 2 otherwise -1 + +if fib is_less_than 0 + + iterator stores 1 + + fyi < store the first two values of the fibonacci sequence > + anteprev_n stores 0 + prev_n stores 1 + + fyi < compute fibonacci numbers until n is reached > + while iterator is_less_than n minus 1 + fib stores anteprev_n plus prev_n + anteprev_n stores prev_n + prev_n stores fib + iterator stores iterator plus 1 + repeat + +otherwise + + show < try a higher value of n for more fun > + +move_on + +show fib \ No newline at end of file diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 31abcc3..2bac28c 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -44,7 +44,12 @@ 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). +assignment(assign(I, E)) --> identifier(I), [stores], selection_inline(E). + +selection(if(B, C, fyi(no_op))) --> [if], boolean(B), command(C), [move_on]. +selection(if(B, C1, C2)) --> [if], boolean(B), command(C1), [otherwise], command(C2), [move_on]. +selection_inline(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]. @@ -57,11 +62,13 @@ command(cmd(C1, C2)) --> assignment(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)) --> selection(C1), command(C2). command(C) --> comment(C). command(C) --> assignment(C). % command(C) --> ternary(C). command(C) --> loop(C). command(C) --> show(C). +command(C) --> selection(C). program(prog(P)) --> command(P). @@ -108,6 +115,8 @@ eval(if(B, T, _), EnvIn, EnvOut, ValueOut) :- eval(if(B, _, F), EnvIn, EnvOut, ValueOut) :- eval(B, EnvIn, EnvTemp, false), eval(F, EnvTemp, EnvOut, ValueOut). +eval(ternary(B, T, F), EnvIn, EnvOut, ValueOut) :- + eval(if(B, T, F), EnvIn, EnvOut, ValueOut). eval(while(B, C), EnvIn, EnvOut, ValueOut) :- eval(B, EnvIn, EnvTemp, true), -- knotmirror 0.0.1 From 1ba6912ecd7e65ce8004f51fd25572eed1543bc8 Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Thu, 28 Apr 2022 17:41:12 -0700 Subject: [PATCH 08/24] Fix bugs in `fibonacci` We've officially written our first bug in Codeable :P Co-authored-by: jgjanes Co-authored-by: Rithvik Arun Co-authored-by: Sai Nishanth Vaka --- data/fibonacci.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/fibonacci.md b/data/fibonacci.md index 9f24f85..9a9a23d 100644 --- a/data/fibonacci.md +++ b/data/fibonacci.md @@ -3,7 +3,7 @@ fyi < example of if statements > n stores 8 -fib stores n if n is_less_than 2 otherwise -1 +fib stores n minus 1 if n is_less_than 3 otherwise -1 if fib is_less_than 0 -- knotmirror 0.0.1 From ffb4ecea4a579b74deb022e43829ff66fd9fa6f0 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 18:09:21 -0700 Subject: [PATCH 09/24] Added range test and basic for loop, in infinite loop --- data/rangeCount.md | 11 +++++++++++ src/runtime/codeable.pl | 11 ++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 data/rangeCount.md diff --git a/data/rangeCount.md b/data/rangeCount.md new file mode 100644 index 0000000..e2bed52 --- /dev/null +++ b/data/rangeCount.md @@ -0,0 +1,11 @@ +i stores 0 +a stores 5 + +fyi < uses i as an iterator for a > +for i in a + + show i + +repeat + + diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 2bac28c..8eb187f 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -51,7 +51,8 @@ selection(if(B, C1, C2)) --> [if], boolean(B), command(C1), [otherwise], command selection_inline(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]. +loop(for(I, E, C)) --> [for], expr(I), [in], expr(E), command(C), [repeat]. + % loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. show(show_string(S)) --> [show], strings(S). show(show_numeric(D)) --> [show], numeric(D). @@ -124,6 +125,14 @@ eval(while(B, C), EnvIn, EnvOut, ValueOut) :- eval(while(B, C), EnvTemp2, EnvOut, ValueOut). eval(while(B, _), EnvIn, EnvOut, _ValueOut) :- eval(B, EnvIn, EnvOut, false). +eval(for(I, E, C), EnvIn, EnvOut, ValueOut) :- + eval(is_less_than(I, E), EnvIn, EnvTemp, true), + update(I, I + 1, EnvTemp, EnvTemp2), + eval(C, EnvTemp2, EnvTemp3, _ValueOut), + eval(for(I, E, C), EnvTemp3, EnvOut, ValueOut). +eval(for(I, E, _), EnvIn, EnvOut, _ValueOut) :- + eval(is_less_than(I, E), EnvIn, EnvOut, false). + eval(expr_plus(Term, Expression), EnvIn, EnvOut, ValueOut) :- eval(Term, EnvIn, EnvTemp, ValTerm), -- knotmirror 0.0.1 From 5b8f00d13c4c805aad98e6e4b0ff82860b422a60 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 19:11:36 -0700 Subject: [PATCH 10/24] Added write outputs --- src/runtime/ide.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/runtime/ide.js b/src/runtime/ide.js index 48a6d45..c730650 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -17,7 +17,7 @@ function hijackConsoleLog() { if (message.toString().indexOf("output") == 1) { consoleLog("[DEBUG] Capturing console output"); let msg = message.toString().slice("[output,".length, -1); - document.getElementById("results").value = msg; + writeOutput(msg); } consoleLog(message); }; @@ -67,6 +67,7 @@ function patchIntermediateCode(session) { function registerRunListener() { let runButton = document.getElementById("run"); runButton.addEventListener("click", (el, ev) => { + writeOutput("Loading..."); let session = pl.create(); session.consult(intermediateCode, { success: () => { @@ -106,7 +107,7 @@ function findAnswer(session) { // Execute the query (execute the goal). session.answer({ success: function (answer) { - document.getElementById("results").value = session.format_answer(answer); + writeOutput(session.format_answer(answer)); console.log(answer); // {X/apple} }, error: function (err) { @@ -124,6 +125,10 @@ function findAnswer(session) { }); } +function writeOutput(message) { + document.getElementById("results").value = message; +} + function tokenizer(fulltext) { var tokens = fulltext.split(/\s/).filter((token) => token.length > 0); return tokens; -- knotmirror 0.0.1 From 5db2598eeeff9b6d11595bd7a4f3a001200b7ee6 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 20:07:33 -0700 Subject: [PATCH 11/24] Added for loop final implementation Co-authored-by: Rithvik Arun Co-authored-by: Joseph Hale Co-authored-by: Sai Nishanth Vaka --- data/rangeCount.md | 9 ++++----- src/runtime/codeable.pl | 23 ++++++++++++++--------- src/runtime/codeable_tests.pl | 4 ++++ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/data/rangeCount.md b/data/rangeCount.md index e2bed52..7b47c24 100644 --- a/data/rangeCount.md +++ b/data/rangeCount.md @@ -1,11 +1,10 @@ +fyi < rangeCount > +fyi < example usage of a for loop > + i stores 0 a stores 5 fyi < uses i as an iterator for a > -for i in a - +for i from 0 to a by 1 show i - repeat - - diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 8eb187f..5bf4aed 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -51,8 +51,8 @@ selection(if(B, C1, C2)) --> [if], boolean(B), command(C1), [otherwise], command selection_inline(ternary(B, T, F)) --> expr(T), [if], boolean(B), [otherwise], expr(F). loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. -loop(for(I, E, C)) --> [for], expr(I), [in], expr(E), command(C), [repeat]. - % loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. +loop(for(I, Start, Stop, 1, C)) --> [for], identifier(I), [from], expr(Start), [to], expr(Stop), command(C), [repeat]. +loop(for(I, Start, Stop, Step, C)) --> [for], identifier(I), [from], expr(Start), [to], expr(Stop), [by], expr(Step), command(C), [repeat]. show(show_string(S)) --> [show], strings(S). show(show_numeric(D)) --> [show], numeric(D). @@ -125,14 +125,19 @@ eval(while(B, C), EnvIn, EnvOut, ValueOut) :- eval(while(B, C), EnvTemp2, EnvOut, ValueOut). eval(while(B, _), EnvIn, EnvOut, _ValueOut) :- eval(B, EnvIn, EnvOut, false). -eval(for(I, E, C), EnvIn, EnvOut, ValueOut) :- - eval(is_less_than(I, E), EnvIn, EnvTemp, true), - update(I, I + 1, EnvTemp, EnvTemp2), - eval(C, EnvTemp2, EnvTemp3, _ValueOut), - eval(for(I, E, C), EnvTemp3, EnvOut, ValueOut). -eval(for(I, E, _), EnvIn, EnvOut, _ValueOut) :- - eval(is_less_than(I, E), EnvIn, EnvOut, false). +eval(for(I, Start, Stop, Step, C), EnvIn, EnvOut, ValueOut) :- + eval(is_less_than(Start, Stop), EnvIn, EnvTemp, true), + eval(Start, EnvTemp, EnvTemp1, ValueStart), + update(I, ValueStart, EnvTemp1, EnvTemp2), + eval(C, EnvTemp2, EnvTemp3, _ValueOut), + eval(Step, EnvTemp3, EnvTemp4, ValueStep), + NextStart is ValueStart + ValueStep, + eval(for(I, expr_term(term_factor(factor_numeric(NextStart))), Stop, Step, C), EnvTemp4, EnvOut, ValueOut). +eval(for(I, Start, Stop, _, _), EnvIn, EnvOut, _ValueOut) :- + eval(Start, EnvIn, EnvTemp, ValueStart), + update(I, ValueStart, EnvTemp, EnvTemp2), + eval(is_less_than(Start, Stop), EnvTemp2, EnvOut, false). eval(expr_plus(Term, Expression), EnvIn, EnvOut, ValueOut) :- eval(Term, EnvIn, EnvTemp, ValTerm), diff --git a/src/runtime/codeable_tests.pl b/src/runtime/codeable_tests.pl index 09e4f97..a9c0936 100644 --- a/src/runtime/codeable_tests.pl +++ b/src/runtime/codeable_tests.pl @@ -22,4 +22,8 @@ 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))))). +test("for loop parses correctly") :- + program(ParseTree, [for, i, from, 0, to, 10, by, 1, show, i, repeat], []), + ParseTree = + :- end_tests(codeable). -- knotmirror 0.0.1 From 30eecede8a4de09db3ca1b3aafaae7f2ebd8dcc4 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 20:39:01 -0700 Subject: [PATCH 12/24] Added loading to output box Updated output field to include output from all responses, not just the last print from parser. Also added a loading notification Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- src/runtime/ide.html | 2 +- src/runtime/ide.js | 49 +++++++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/runtime/ide.html b/src/runtime/ide.html index 1b33998..e231815 100644 --- a/src/runtime/ide.html +++ b/src/runtime/ide.html @@ -13,7 +13,7 @@
- +
diff --git a/src/runtime/ide.js b/src/runtime/ide.js index c730650..e61222b 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -1,4 +1,6 @@ let INTERPRETER_CODE_PATH = "codeable.pl"; +let LOADING_MSG = "Loading..."; +let OUTPUT_LABEL = "Output"; let intermediateCode = ""; function populateCodeArea() { @@ -64,21 +66,30 @@ function patchIntermediateCode(session) { }); } +function prepareComputation(callback) { + document.getElementById("output-label").innerHTML = LOADING_MSG; + writeOutput("", overwrite = true); + setTimeout(() => { + callback(); + }, 0) +} + function registerRunListener() { let runButton = document.getElementById("run"); runButton.addEventListener("click", (el, ev) => { - writeOutput("Loading..."); - let session = pl.create(); - session.consult(intermediateCode, { - success: () => { - console.log("[INFO] Loaded interpreter source code"); - loadQuery(session); - }, - error: (err) => { - console.log("[ERROR] Failed to load interpreter source code"); - console.log(err); - }, - }); + prepareComputation(() => { + let session = pl.create(); + session.consult(intermediateCode, { + success: () => { + console.log("[INFO] Loaded interpreter source code"); + loadQuery(session); + }, + error: (err) => { + console.log("[ERROR] Failed to load interpreter source code"); + console.log(err); + }, + }); + }) }); } @@ -116,6 +127,7 @@ function findAnswer(session) { }, fail: function () { /* No more answers */ + document.getElementById("output-label").innerHTML = OUTPUT_LABEL; console.log("No more answers!"); }, limit: function () { @@ -125,8 +137,12 @@ function findAnswer(session) { }); } -function writeOutput(message) { - document.getElementById("results").value = message; +function writeOutput(message, overwrite = false) { + if (overwrite) { + document.getElementById("results").value = message; + } else { + document.getElementById("results").value += `${message}\n`; + } } function tokenizer(fulltext) { @@ -139,11 +155,6 @@ function main() { hijackConsoleLog(); prepareInterpreter(); registerRunListener(); - - var tokens = tokenizer( - 'tower-of-hanoi disks with source with target with medium if disks is-greater-than 0 disks1 equals subtraction of disks with 1 tower-of-hanoi of disks1 with source with medium with target show-value-of " Move disk " with disks with " from rod " with source with " with rod " with target tower-of-hanoi of disks1 with medium with target with source move-on answer equals no-answer' - ); - console.log(tokens); } main(); -- knotmirror 0.0.1 From 44a215e1796bf011a30ed32998df0cd723972ad1 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:21:27 -0700 Subject: [PATCH 13/24] Added Command line separatable code Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- src/runtime/command_line_executable.js | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/runtime/command_line_executable.js diff --git a/src/runtime/command_line_executable.js b/src/runtime/command_line_executable.js new file mode 100644 index 0000000..d3cac94 --- /dev/null +++ b/src/runtime/command_line_executable.js @@ -0,0 +1,72 @@ +const fs = require('fs'); +const tokenizer = require('/ide') +const tau_prolog = require('/tau-prolog') + +function readFileLoad(fileName, callback){ + + return callback(data); +} + +function tokenizeExecute(fileName){ + fs.readFile(fileName, 'utf8', (err, data) => { + if (err) { + console.error(err); + return; + } + console.log(data); + }); + let session = pl.create(); + session.consult(intermediateCode, { + success: () => { + console.log("[INFO] Loaded interpreter source code"); + loadQueryEx(session); + }, + error: (err) => { + console.log("[ERROR] Failed to load interpreter source code"); + console.log(err); + }, + }); +} + +// Create the query (parse the query). +function loadQueryEx(session, programText) { + var tokens = tokenizer.tokenizer(programText); + var formattedTokens = JSON.stringify(tokens).replaceAll('"', ""); + var completeQuery = `program(P, ${formattedTokens}, []), write(P), eval(P, [], EnvOut, ValueOut).`; + console.log(completeQuery); + session.query(completeQuery, { + success: function (goal) { + /* Goal parsed correctly */ + console.log("Successfully parsed query!"); + console.log(goal); + findAnswerEx(session); + }, + error: function (err) { + console.log("[ERROR] Failed to parse query"); + console.log(err); + }, + }); + } + + function findAnswerEx(session) { + // Execute the query (execute the goal). + session.answer({ + success: function (answer) { + writeOutput(session.format_answer(answer)); + console.log(answer); // {X/apple} + }, + error: function (err) { + /* Uncaught error */ + console.log("Error: " + err); + }, + fail: function () { + /* No more answers */ + console.log("No more answers!"); + }, + limit: function () { + /* Limit exceeded */ + console.log("Limit exceeded!"); + }, + }); + } + \ No newline at end of file -- knotmirror 0.0.1 From d5eb5d035e17c6c8daeb52774772ac0adee70772 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:43:36 -0700 Subject: [PATCH 14/24] Cleaned up directory Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- .gitignore | 135 +++++++++- data/{factorial.md => factorial.code} | 0 data/{fibonacci.md => fibonacci.code} | 5 +- data/hello_world.code | 2 + ...atic_formula.md => quadratic_formula.code} | 0 data/{rangeCount.md => range_count.code} | 0 data/selection-sort.md | 10 - data/tower-of-hanoi.md | 11 - src/runtime/command_line_executable.js | 55 ++-- src/runtime/jhaleAssign3.pl | 239 ------------------ src/runtime/package-lock.json | 135 ++++++++++ src/runtime/package.json | 5 + 12 files changed, 308 insertions(+), 289 deletions(-) rename data/{factorial.md => factorial.code} (100%) rename data/{fibonacci.md => fibonacci.code} (87%) create mode 100644 data/hello_world.code rename data/{quadratic_formula.md => quadratic_formula.code} (100%) rename data/{rangeCount.md => range_count.code} (100%) delete mode 100644 data/selection-sort.md delete mode 100644 data/tower-of-hanoi.md delete mode 100644 src/runtime/jhaleAssign3.pl create mode 100644 src/runtime/package-lock.json create mode 100644 src/runtime/package.json diff --git a/.gitignore b/.gitignore index 06fafc4..f3ca41f 100644 --- a/.gitignore +++ b/.gitignore @@ -303,4 +303,137 @@ TSWLatexianTemp* # REVTeX puts footnotes in the bibliography by default, unless the nofootinbib # option is specified. Footnotes are the stored in a file with suffix Notes.bib. # Uncomment the next line to have this generated file ignored. -#*Notes.bib \ No newline at end of file +#*Notes.bib +src/runtime/node_modules/* + +# Node.js .gitignore (from https://github.com/github/gitignore/blob/main/Node.gitignore) +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* \ No newline at end of file diff --git a/data/factorial.md b/data/factorial.code similarity index 100% rename from data/factorial.md rename to data/factorial.code diff --git a/data/fibonacci.md b/data/fibonacci.code similarity index 87% rename from data/fibonacci.md rename to data/fibonacci.code index 9a9a23d..ba4008c 100644 --- a/data/fibonacci.md +++ b/data/fibonacci.code @@ -22,8 +22,9 @@ if fib is_less_than 0 repeat otherwise - - show < try a higher value of n for more fun > + + message stores < try a higher value of n for more fun > + show message move_on diff --git a/data/hello_world.code b/data/hello_world.code new file mode 100644 index 0000000..39ffd8e --- /dev/null +++ b/data/hello_world.code @@ -0,0 +1,2 @@ +greeting stores < hello world > +show greeting \ No newline at end of file diff --git a/data/quadratic_formula.md b/data/quadratic_formula.code similarity index 100% rename from data/quadratic_formula.md rename to data/quadratic_formula.code diff --git a/data/rangeCount.md b/data/range_count.code similarity index 100% rename from data/rangeCount.md rename to data/range_count.code diff --git a/data/selection-sort.md b/data/selection-sort.md deleted file mode 100644 index 25c4317..0000000 --- a/data/selection-sort.md +++ /dev/null @@ -1,10 +0,0 @@ -selection-sort with dataList -returnList equals minimum-value of dataList -fyi array operation delete minumum element -fyi keeping deleting the element from list until empty -fyi append each element to returnList -answer equals returnList - - - -minimum-value with dataList diff --git a/data/tower-of-hanoi.md b/data/tower-of-hanoi.md deleted file mode 100644 index fa45dbf..0000000 --- a/data/tower-of-hanoi.md +++ /dev/null @@ -1,11 +0,0 @@ -tower-of-hanoi disks with source with target with medium -if disks is-greater-than 0 -disks1 equals substraction of disks with 1 -tower-of-hanoi of disks1 with source with medium with target -show-value-of "Move disk " with disks with " from rod " with source with " with rod " with target -tower-of-hanoi of disks1 with medium with target with source -move-on -answer equals no-answer - -fyi example of recursion -fyi example of if blocks \ No newline at end of file diff --git a/src/runtime/command_line_executable.js b/src/runtime/command_line_executable.js index d3cac94..5bf00b0 100644 --- a/src/runtime/command_line_executable.js +++ b/src/runtime/command_line_executable.js @@ -1,36 +1,37 @@ const fs = require('fs'); -const tokenizer = require('/ide') -const tau_prolog = require('/tau-prolog') - -function readFileLoad(fileName, callback){ - - return callback(data); -} +const pl = require('tau-prolog'); +let INTERPRETER_CODE_PATH = "codeable.pl"; function tokenizeExecute(fileName){ - fs.readFile(fileName, 'utf8', (err, data) => { - if (err) { - console.error(err); - return; - } - console.log(data); - }); + var data = "" + fs.readFile(fileName, 'utf8', (err, data) => { + if (err) { + console.error(err); + return; + } + // console.log(data); let session = pl.create(); - session.consult(intermediateCode, { - success: () => { - console.log("[INFO] Loaded interpreter source code"); - loadQueryEx(session); - }, - error: (err) => { - console.log("[ERROR] Failed to load interpreter source code"); - console.log(err); - }, + session.consult(INTERPRETER_CODE_PATH, { + success: () => { + console.log("[INFO] Loaded interpreter source code"); + loadQueryEx(session, data); + }, + error: (err) => { + console.log("[ERROR] Failed to load interpreter source code"); + console.log(err); + }, }); + }); +} + +function tokenizer(fulltext) { + var tokens = fulltext.split(/\s/).filter((token) => token.length > 0); + return tokens; } // Create the query (parse the query). function loadQueryEx(session, programText) { - var tokens = tokenizer.tokenizer(programText); + var tokens = tokenizer(programText); var formattedTokens = JSON.stringify(tokens).replaceAll('"', ""); var completeQuery = `program(P, ${formattedTokens}, []), write(P), eval(P, [], EnvOut, ValueOut).`; console.log(completeQuery); @@ -52,7 +53,7 @@ function loadQueryEx(session, programText) { // Execute the query (execute the goal). session.answer({ success: function (answer) { - writeOutput(session.format_answer(answer)); + console.log("==:ANSWER:==") console.log(answer); // {X/apple} }, error: function (err) { @@ -69,4 +70,6 @@ function loadQueryEx(session, programText) { }, }); } - \ No newline at end of file + + const myArgs = process.argv.slice(2); + tokenizeExecute(myArgs[0]); diff --git a/src/runtime/jhaleAssign3.pl b/src/runtime/jhaleAssign3.pl deleted file mode 100644 index 4eb371c..0000000 --- a/src/runtime/jhaleAssign3.pl +++ /dev/null @@ -1,239 +0,0 @@ -% :- use_rendering(svgtree). % Only works in SWISH.swi-prolog.org - -/** - * codeable_version(-Major,-Minor,-Patch) is det. - */ -codeable_version(0,0,1). - -%%%%% Token Parser %%%%%% -% Parser - Numercis -number(t_number(N)) --> [N], {number(N)}. - -% v3 (Heavily inspired by M2.1 - slide 59) -% chars([X|Y]) --> char(X), chars(Y). -% chars([]) --> []. - -% char(X) --> [X], { is_char(X) }. - -% string(X) --> ['\"'], char(X), ['\"']. -% string(X) --> ['\"'], char(X), [' '], char(X), ['\"']. -% string(X) --> ['\"'], char(X), [' '], string(X), ['\"']. -identifier(id(A)) --> [a]. - -factor(factor_number(F)) --> number(F). -factor(factor_identifier(F)) --> identifier(F). -factor(factor_expression(F)) --> ['('], expr(F), [')']. - -term(term_factor(T)) --> factor(T). -term(term_times(T1, T2)) --> factor(T1), [times], term(T2). -term(term_divide(T1, T2)) --> factor(T1), [divided-by], term(T2). - -expr(expr_term(E)) --> term(E). -expr(expr_plus(E1, E2)) --> term(E1), [plus], expr(E2). -expr(expr_minus(E1, E2)) --> term(E1), [minus], expr(E2). -% expr(expr_ternary(T)) --> ternary(T). - -boolean(true) --> [true]. -boolean(false) --> [false]. -boolean(not(B)) --> [not], boolean(B). -boolean(equals(E1, E2)) --> expr(E1), [equals], expr(E2). -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). -loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. -loop(for(I1, I2, C)) --> [for], identifier(I1), [from], identifier(I2), command(C), [repeat]. - -% show(show_char(C)) --> [show], char(C). -% show(show_string(S)) --> [show], string(S). -show(show_digit(D)) --> [show], digit(D). -show(show_identifier(I)) --> [show], identifier(I). - -command(C) --> assignment(C). -command(C) --> ternary(C). -command(C) --> loop(C). -command(C) --> show(C). -command(cmd(C1, C2)) --> assignment(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). - - -program(prog(P)) --> command(P). - -% Parser - Functions - -% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). - -% Functions eval - -% 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) - * - * Evaluates the parse tree rooted at Node, with the environment EnvIn, - * and returns the environment EnvOut and the value ValueOut. - * - * The environment is a list of pairs (Identifier, Value) where Identifier - * is a string and Value is an integer. - * - */ -eval(prog(P), EnvIn, EnvOut, ValueOut) :- - eval(P, EnvIn, EnvOut, ValueOut). - -eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- - eval(C1, EnvIn, EnvTemp, _ValueOut), - eval(C2, EnvTemp, EnvOut, ValueOut). - -eval(assign(I, E), EnvIn, EnvOut, ValueOut) :- - eval(E, EnvIn, EnvTemp, ValueOut), - update(I, ValueOut, EnvTemp, EnvOut). - -eval(if(B, T, _), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, true), - eval(T, EnvTemp, EnvOut, ValueOut). -eval(if(B, _, F), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, false), - eval(F, EnvTemp, EnvOut, ValueOut). - -eval(while(B, C), EnvIn, EnvOut, ValueOut) :- - eval(B, EnvIn, EnvTemp, true), - eval(C, EnvTemp, EnvTemp2, _ValueOut), - eval(while(B, C), EnvTemp2, EnvOut, ValueOut). -eval(while(B, _), EnvIn, EnvOut, _ValueOut) :- - eval(B, EnvIn, EnvOut, false). - -eval(expr_plus(Term, Expression), EnvIn, EnvOut, ValueOut) :- - eval(Term, EnvIn, EnvTemp, ValTerm), - eval(Expression, EnvTemp, EnvOut, ValExpr), - ValueOut is ValTerm + ValExpr. -eval(expr_minus(Term, Expression), EnvIn, EnvOut, ValueOut) :- - eval(Term, EnvIn, EnvTemp, ValTerm), - eval(Expression, EnvTemp, EnvOut, ValExpr), - ValueOut is ValTerm + (0 - ValExpr). -eval(expr_term(T), EnvIn, EnvOut, ValueOut) :- - eval(T, EnvIn, EnvOut, ValueOut). -eval(expr_assign(A), EnvIn, EnvOut, ValueOut) :- - eval(A, EnvIn, EnvOut, ValueOut). - -eval(term_times(Factor, Term), EnvIn, Env2Out, ValueOut) :- - eval(Factor, EnvIn, Env1Out, Val1Out), - eval(Term, Env1Out, Env2Out, Val2Out), - ValueOut is Val1Out * Val2Out. -eval(term_divide(Factor, Term), EnvIn, Env2Out, ValueOut) :- - eval(Factor, EnvIn, Env1Out, Val1Out), - eval(Term, Env1Out, Env2Out, Val2Out), - ValueOut is Val1Out * (1 / Val2Out). -eval(term_factor(F), EnvIn, EnvOut, ValueOut) :- - eval(F, EnvIn, EnvOut, ValueOut). - -eval(factor_digit(D), EnvIn, EnvIn, D). -eval(factor_identifier(I), EnvIn, EnvIn, Value) :- - lookup(I, EnvIn, Value). -eval(factor_expression(E), EnvIn, EnvOut, Value) :- - eval(E, EnvIn, EnvOut, Value). - -eval(true, EnvIn, EnvIn, true). -eval(false, EnvIn, EnvIn, false). -eval(not(B), EnvIn, EnvOut, false) :- - eval(B, EnvIn, EnvOut, true). -eval(not(B), EnvIn, EnvOut, true) :- - eval(B, EnvIn, EnvOut, false). -eval(equals(E1, E2), EnvIn, EnvOut, true) :- - eval(E1, EnvIn, EnvTemp, ValueOut), - eval(E2, EnvTemp, EnvOut, ValueOut). -eval(equals(E1, E2), EnvIn, EnvOut, false) :- - eval(E1, EnvIn, EnvTemp, ValueOut1), - eval(E2, EnvTemp, EnvOut, ValueOut2), - ValueOut1 =\= ValueOut2. - -eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). -eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). -eval(show_digit(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). -eval(show_identifier(I), EnvIn, EnvIn, _ValueOut) :- - lookup(I, EnvIn, Value), - write([output, Value]). - -/** - * lookup(+Identifier, +Env, -Value) - * - * Looks up the Value of Identifier in Env. - */ -lookup(Identifier, [(Identifier, Value) | _], Value). -lookup(Identifier, [(OtherIdentifier, _) | RemainingEnvironment], Value) :- - Identifier \= OtherIdentifier, - lookup(Identifier, RemainingEnvironment, Value). - -/** - * declare(+Identifier, +EnvIn, -EnvOut) - * - * Adds a new binding (Identifier, _) to EnvIn and returns EnvOut. - * - * If Identifier is already bound in EnvIn, it is not rebound. - */ -declare(Identifier, [], [(Identifier, _)]). -declare( - Identifier, - [(Identifier, Value) | RemainingEnvironment], - [(Identifier, Value) | RemainingEnvironment] -). -declare(Identifier, [H | RemainingEnvironment], [H | NewEnvironment]) :- - declare(Identifier, RemainingEnvironment, NewEnvironment). - -/** - * update(+Identifier, +Value, +EnvIn, -EnvOut) - * - * Updates the binding of Identifier in EnvIn to Value and returns EnvOut. - */ -update(Identifier, Value, [], [(Identifier, Value)]). -update( - Identifier, - Value, - [(Identifier, _) | RemainingEnvironment], - [(Identifier, Value) | RemainingEnvironment] -). -update( - Identifier, - Value, - [(OtherIdentifier, OtherValue) | RemainingEnvironment], - [(OtherIdentifier, OtherValue) | NewEnvironment] -) :- - Identifier \= OtherIdentifier, - update(Identifier, Value, RemainingEnvironment, NewEnvironment). - - -/** - * program_eval(+Program, +InitialX, +InitialY, -FinalZ) - * - * Evaluates the Program with the initial value of X and Y - * and returns the final value of Z. - */ -program_eval(P, X, Y, Z) :- - update(x, X, [], EnvX), - update(y, Y, EnvX, EnvY), - eval(P, EnvY, EnvOut, _ValueOut), - lookup(z, EnvOut, Z). - -digit(0) --> [0]. -digit(1) --> [1]. -digit(2) --> [2]. -digit(3) --> [3]. -digit(4) --> [4]. -digit(5) --> [5]. -digit(6) --> [6]. -digit(7) --> [7]. -digit(8) --> [8]. -digit(9) --> [9]. - -% identifier(WORD) --> { var(WORD), ! }, -% chars(CHARS), { atom_codes(WORD, CHARS) }. -% identifier(WORD) --> { nonvar(WORD) }, -% { atom_codes(WORD, CHARS) }, chars(CHARS). - -% is_char(X) :- X >= 0'a, X =< 0'z, !. -% is_char(X) :- X >= 0'A, X =< 0'Z, !. -% is_char(X) :- X >= 0'0, X =< 0'9, !. -% is_char(0'_). \ No newline at end of file diff --git a/src/runtime/package-lock.json b/src/runtime/package-lock.json new file mode 100644 index 0000000..2e1ab98 --- /dev/null +++ b/src/runtime/package-lock.json @@ -0,0 +1,135 @@ +{ + "name": "runtime", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "tau-prolog": "^0.3.2" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qunit": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.18.2.tgz", + "integrity": "sha512-Ux+x9pIU38/F+r3jOl35QzGHPPupMifUvhczCqHgzYWX76fCjPg6VqM84ox1D57fhAXHtpS4Jl91EV8gDoCHPg==", + "dependencies": { + "commander": "7.2.0", + "node-watch": "0.7.3", + "tiny-glob": "0.2.9" + }, + "bin": { + "qunit": "bin/qunit.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readline-sync": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", + "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tau-prolog": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tau-prolog/-/tau-prolog-0.3.2.tgz", + "integrity": "sha512-DlC8MBYtDEdfX0EdD5eNV3W7uPkqUO0vfck/fawt2lH85exj2rKiKxDkmkPa6DVg2thxnDxI+8UbxHs7rXb4Fg==", + "dependencies": { + "qunit": "^2.11.1", + "readline-sync": "1.4.9" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + } + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==" + }, + "qunit": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.18.2.tgz", + "integrity": "sha512-Ux+x9pIU38/F+r3jOl35QzGHPPupMifUvhczCqHgzYWX76fCjPg6VqM84ox1D57fhAXHtpS4Jl91EV8gDoCHPg==", + "requires": { + "commander": "7.2.0", + "node-watch": "0.7.3", + "tiny-glob": "0.2.9" + } + }, + "readline-sync": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", + "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=" + }, + "tau-prolog": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tau-prolog/-/tau-prolog-0.3.2.tgz", + "integrity": "sha512-DlC8MBYtDEdfX0EdD5eNV3W7uPkqUO0vfck/fawt2lH85exj2rKiKxDkmkPa6DVg2thxnDxI+8UbxHs7rXb4Fg==", + "requires": { + "qunit": "^2.11.1", + "readline-sync": "1.4.9" + } + }, + "tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "requires": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + } + } +} diff --git a/src/runtime/package.json b/src/runtime/package.json new file mode 100644 index 0000000..d0d4d36 --- /dev/null +++ b/src/runtime/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "tau-prolog": "^0.3.2" + } +} -- knotmirror 0.0.1 From 2a8260dac5ac78d41ab2f8aeadb69045583b318d Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:43:57 -0700 Subject: [PATCH 15/24] Updated Grammar to match to current parser Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- doc/grammar.md | 64 ++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/doc/grammar.md b/doc/grammar.md index a9452dc..b54e12e 100644 --- a/doc/grammar.md +++ b/doc/grammar.md @@ -1,30 +1,31 @@ // Initial Definitions -`identifier` := \w+(-\w+)* -`identifier_answer` := answer -`identifier_answer` := no-answer +`identifier` := \w+ +`command` := `comment` +`command` := `assignment` +`command` := `loop` +`command` := `show` +`command` := `selection` +`command` := `command` `command` + +`program` := `command` -`block` := `assignment` \n -`block` := `assignment` \n `block` -`block` := `print_statement` \n -`block` := `print_statement` \n `block` // Requirement 1a `boolean` := true `boolean` := false -`expression_boolean` := `expression_boolean` and `expression_boolean` -`expression_boolean` := `expression_boolean` or `expression_boolean` -`expression_boolean` := not `expression_boolean` +`boolean` := not `boolean` +`boolean` := `expression` and `expression` +`boolean` := `expression` or `expression` +`boolean` := `expression` is_greater_than `expression` +`boolean` := `expression` is_less_than `expression` +`boolean` := `expression` equals `expression` // Requirement 1b `number` := [0-9]+(\.[0-9]+)? `expression` := `number` -`expression` := `boolean` -`expression` := `string` `expression` := `identifier` -`expression` := `ternary` -`expression` := `function_call` `expression` := `expression` plus `expression` `expression` := `expression` minus `expression` `expression` := `expression` times `expression` @@ -37,42 +38,29 @@ // Requirement 2 `assignment` := `identifier` stores `expression` -`assignment_answer` := `identifier_answer` stores `expression` +`assignment` := `identifier` stores `string` +`assignment` := `identifier` stores `ternary` // Requirement 3a -`ternary` := `expression` if `expression_boolean` otherwise `expression` +`ternary` := `expression` if `boolean` otherwise `expression` // Requirement 3b -`if_statement` := if `expression_boolean` \n `block` \n move-on -`if_statement` := if `expression_boolean` \n `block` \n otherwise \n `block` \n move-on -`if_statement` := if `expression_boolean` \n `block` \n otherwise `if_statement` \n move-on +`if_statement` := if `boolean` `command` move-on +`if_statement` := if `boolean` `command` otherwise `command` move-on // Requirement 4a -`loop_for` := for `identifier` from `identifer` \n `block` \n repeat +`loop_for` := for `identifier` from `expression` to `expression` by `expression` `command` repeat // Requirement 4b -`loop_while` := while `expression_boolean` \n `block` \n repeat +`loop_while` := while `boolean` `command` repeat // Requirement 4c -// TODO - I'm thinking that "range(2,5)" could be a function that returns an iterable collection. That's how Python does it... +`loop_for` := for `identifier` from `expression` to `expression` `command` repeat // Requirement 5 -`print_statement` := show `identifier` - -// Other Features: Functions -`argument` := `identifier` -`argument_list` := `argument` -`argument_list` := `argument` with `argument_list` - -`function_definition` := `identifier` needs `argument_list` \n `block` \n `assignment_answer` \n - -`function_call` := `identifier` of `argument_list` +`print` := show `string` +`print` := show `number` +`print` := show `identifier` // Other Features: Comments `comment` := fyi `string` \n - -// Comparison Operators -`greater_than` := `expression` is-greater-than `expression` -`less_than` := `expression` is-less-than `expression` -`equal-to` := `expression` is-equal-to `expression` - -- knotmirror 0.0.1 From f173c717a45b5f38e56196dcb441f31010fb7416 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:44:50 -0700 Subject: [PATCH 16/24] Removed unused and commented code on codeable.pl Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- src/runtime/codeable.pl | 66 +++++++---------------------------------- 1 file changed, 11 insertions(+), 55 deletions(-) diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 5bf4aed..6d6c620 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -5,18 +5,16 @@ */ codeable_version(0,0,1). -%%%%% Token Parser %%%%%% -% Parser - Numercis +/** + * Token Parser + */ numeric(N) --> [N], {number(N)}. -% v3 (Heavily inspired by M2.1 - slide 59) -char(C) --> [C], { char_type(C, alpha) }. - identifier(I) --> [I], {atom(I)}. word([W]) --> identifier(W). word([W1 | W2]) --> [W1], word(W2), { atom(W1), W1 \= <, W1 \= > }. -strings(S) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. +strings(str(S)) --> [<], word(W), [>], { atomic_list_concat(W, ' ', S) }. comment(fyi(S)) --> [fyi], strings(S). @@ -34,7 +32,6 @@ term(term_divide(T1, T2)) --> factor(T1), [divided_by], term(T2). expr(expr_term(E)) --> term(E). expr(expr_plus(E1, E2)) --> term(E1), [plus], expr(E2). expr(expr_minus(E1, E2)) --> term(E1), [minus], expr(E2). -% expr(expr_ternary(T)) --> ternary(T). boolean(true) --> [true]. boolean(false) --> [false]. @@ -44,15 +41,17 @@ 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). +assignment(assign(I, E)) --> identifier(I), [stores], strings(E). assignment(assign(I, E)) --> identifier(I), [stores], selection_inline(E). selection(if(B, C, fyi(no_op))) --> [if], boolean(B), command(C), [move_on]. selection(if(B, C1, C2)) --> [if], boolean(B), command(C1), [otherwise], command(C2), [move_on]. selection_inline(ternary(B, T, F)) --> expr(T), [if], boolean(B), [otherwise], expr(F). -loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. -loop(for(I, Start, Stop, 1, C)) --> [for], identifier(I), [from], expr(Start), [to], expr(Stop), command(C), [repeat]. loop(for(I, Start, Stop, Step, C)) --> [for], identifier(I), [from], expr(Start), [to], expr(Stop), [by], expr(Step), command(C), [repeat]. +loop(for(I, Start, Stop, 1, C)) --> [for], identifier(I), [from], expr(Start), [to], expr(Stop), command(C), [repeat]. + +loop(while(B, C)) --> [while], boolean(B), command(C), [repeat]. show(show_string(S)) --> [show], strings(S). show(show_numeric(D)) --> [show], numeric(D). @@ -60,33 +59,17 @@ show(show_identifier(I)) --> [show], identifier(I). command(cmd(C1, C2)) --> comment(C1), command(C2). command(cmd(C1, C2)) --> assignment(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)) --> selection(C1), command(C2). command(C) --> comment(C). command(C) --> assignment(C). -% command(C) --> ternary(C). command(C) --> loop(C). command(C) --> show(C). command(C) --> selection(C). program(prog(P)) --> command(P). -% Parser - Functions - -% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). - -% functions(t_functions(Id, Args,Y, Val)) --> identifier(Id), decl_a1(Args), [needs], comm(Y), [answer], [equals], result(Val). -% decl_al([]) --> []. -% decl_al([H|T]) --> identifier(H), decl_al(T). - -% Functions eval - -% 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) * @@ -100,7 +83,9 @@ program(prog(P)) --> command(P). eval(prog(P), EnvIn, EnvOut, ValueOut) :- eval(P, EnvIn, EnvOut, ValueOut). -eval(fyi(_S), EnvIn, EnvIn, _ValueOut). +eval(fyi(S), EnvIn, EnvIn, S). + +eval(str(S), EnvIn, EnvIn, S). eval(cmd(C1, C2), EnvIn, EnvOut, ValueOut) :- eval(C1, EnvIn, EnvTemp, _ValueOut), @@ -220,22 +205,6 @@ lookup(Identifier, [(OtherIdentifier, _) | RemainingEnvironment], Value) :- Identifier \= OtherIdentifier, lookup(Identifier, RemainingEnvironment, Value). -/** - * declare(+Identifier, +EnvIn, -EnvOut) - * - * Adds a new binding (Identifier, _) to EnvIn and returns EnvOut. - * - * If Identifier is already bound in EnvIn, it is not rebound. - */ -declare(Identifier, [], [(Identifier, _)]). -declare( - Identifier, - [(Identifier, Value) | RemainingEnvironment], - [(Identifier, Value) | RemainingEnvironment] -). -declare(Identifier, [H | RemainingEnvironment], [H | NewEnvironment]) :- - declare(Identifier, RemainingEnvironment, NewEnvironment). - /** * update(+Identifier, +Value, +EnvIn, -EnvOut) * @@ -256,16 +225,3 @@ update( ) :- Identifier \= OtherIdentifier, update(Identifier, Value, RemainingEnvironment, NewEnvironment). - - -/** - * program_eval(+Program, +InitialX, +InitialY, -FinalZ) - * - * Evaluates the Program with the initial value of X and Y - * and returns the final value of Z. - */ -program_eval(P, X, Y, Z) :- - update(x, X, [], EnvX), - update(y, Y, EnvX, EnvY), - eval(P, EnvY, EnvOut, _ValueOut), - lookup(z, EnvOut, Z). \ No newline at end of file -- knotmirror 0.0.1 From 38e3192a594bcdc9661b1ededb6d75b6dc2119db Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:57:21 -0700 Subject: [PATCH 17/24] Added readme on how to access terminal Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04e7e61..a865fbf 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,9 @@ Windows or Mac OS) - Directions/instructions to build and run your language (compiler/runtime). - ONE LINE of bash script that builds the compiler and ONE LINE that runs the runtime. -- Link to the YouTube video \ No newline at end of file +- Link to the YouTube video + +In order to make terminal output, you can input a command in this format when on the src\runtime: +``` +node .\codeable_cli.js "../../data/fibonacci.code" +``` \ No newline at end of file -- knotmirror 0.0.1 From 2024e4a1f467139bca7fbcb960dec29625b27625 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:57:31 -0700 Subject: [PATCH 18/24] Updated CLI runner Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- .../{command_line_executable.js => codeable_cli.js} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename src/runtime/{command_line_executable.js => codeable_cli.js} (88%) diff --git a/src/runtime/command_line_executable.js b/src/runtime/codeable_cli.js similarity index 88% rename from src/runtime/command_line_executable.js rename to src/runtime/codeable_cli.js index 5bf00b0..f82212c 100644 --- a/src/runtime/command_line_executable.js +++ b/src/runtime/codeable_cli.js @@ -33,13 +33,13 @@ function tokenizer(fulltext) { function loadQueryEx(session, programText) { var tokens = tokenizer(programText); var formattedTokens = JSON.stringify(tokens).replaceAll('"', ""); - var completeQuery = `program(P, ${formattedTokens}, []), write(P), eval(P, [], EnvOut, ValueOut).`; - console.log(completeQuery); + var completeQuery = `program(P, ${formattedTokens}, []), eval(P, [], EnvOut, ValueOut).`; + // console.log(completeQuery); session.query(completeQuery, { success: function (goal) { /* Goal parsed correctly */ console.log("Successfully parsed query!"); - console.log(goal); + // console.log(goal); findAnswerEx(session); }, error: function (err) { @@ -53,8 +53,8 @@ function loadQueryEx(session, programText) { // Execute the query (execute the goal). session.answer({ success: function (answer) { - console.log("==:ANSWER:==") - console.log(answer); // {X/apple} + // console.log("==:ANSWER:==") + //console.log(answer); // {X/apple} }, error: function (err) { /* Uncaught error */ -- knotmirror 0.0.1 From 62130c1140948e5af72ffc5b6ea44bbec39f8f2c Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:57:53 -0700 Subject: [PATCH 19/24] Update fib to include otherwise branch Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- data/fibonacci.code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/fibonacci.code b/data/fibonacci.code index ba4008c..ec341d3 100644 --- a/data/fibonacci.code +++ b/data/fibonacci.code @@ -1,7 +1,7 @@ fyi < fibonacci > fyi < example of if statements > -n stores 8 +n stores 2 fib stores n minus 1 if n is_less_than 3 otherwise -1 -- knotmirror 0.0.1 From aa05bd8767253d893407e596e530359914679b84 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:58:03 -0700 Subject: [PATCH 20/24] Added str to tree Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- src/runtime/codeable.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/codeable.pl b/src/runtime/codeable.pl index 6d6c620..b02a744 100644 --- a/src/runtime/codeable.pl +++ b/src/runtime/codeable.pl @@ -189,7 +189,7 @@ eval(is_greater_than(E1, E2), EnvIn, EnvOut, false) :- ValueOut1 =< ValueOut2. eval(show_char(C), EnvIn, EnvIn, _ValueOut) :-write([output, C]). -eval(show_string(S), EnvIn, EnvIn, _ValueOut) :- write([output, S]). +eval(show_string(str(S)), EnvIn, EnvIn, _ValueOut) :- write([output, S]). eval(show_numeric(D), EnvIn, EnvIn, _ValueOut) :- write([output, D]). eval(show_identifier(I), EnvIn, EnvIn, _ValueOut) :- lookup(I, EnvIn, Value), -- knotmirror 0.0.1 From c3f93a10401196de2ddf642574a64718cb5d7374 Mon Sep 17 00:00:00 2001 From: jgjanes Date: Thu, 28 Apr 2022 21:58:29 -0700 Subject: [PATCH 21/24] Full release on IDE Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- src/runtime/ide.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/runtime/ide.js b/src/runtime/ide.js index e61222b..bf9f2fc 100644 --- a/src/runtime/ide.js +++ b/src/runtime/ide.js @@ -4,7 +4,7 @@ let OUTPUT_LABEL = "Output"; let intermediateCode = ""; function populateCodeArea() { - var sampleProgram = "show 25"; + var sampleProgram = "greeting stores < hello world >\nshow greeting"; var codeArea = document.getElementById("code"); codeArea.value = sampleProgram; } @@ -12,6 +12,7 @@ function populateCodeArea() { function hijackConsoleLog() { let consoleLog = console.log; console.log = (message) => { + // debugger if (message.toString().indexOf("codeable_version") > 0) { consoleLog("[DEBUG] Capturing intermediate code"); intermediateCode = message; @@ -98,7 +99,7 @@ function loadQuery(session) { var programText = document.getElementById("code").value; var tokens = tokenizer(programText); var formattedTokens = JSON.stringify(tokens).replaceAll('"', ""); - var completeQuery = `program(P, ${formattedTokens}, []), write(P), program_eval(P, 2, 3, Z).`; + var completeQuery = `program(P, ${formattedTokens}, []), eval(P, [], EnvOut, ValueOut).`; console.log(completeQuery); session.query(completeQuery, { success: function (goal) { @@ -118,8 +119,8 @@ function findAnswer(session) { // Execute the query (execute the goal). session.answer({ success: function (answer) { - writeOutput(session.format_answer(answer)); - console.log(answer); // {X/apple} + console.log(session.format_answer(answer)); + document.getElementById("output-label").innerHTML = OUTPUT_LABEL; }, error: function (err) { /* Uncaught error */ @@ -127,7 +128,6 @@ function findAnswer(session) { }, fail: function () { /* No more answers */ - document.getElementById("output-label").innerHTML = OUTPUT_LABEL; console.log("No more answers!"); }, limit: function () { -- knotmirror 0.0.1 From 1782be394447d647594aa6886e53fbb496c3aaad Mon Sep 17 00:00:00 2001 From: jgjanes Date: Fri, 29 Apr 2022 08:06:54 -0700 Subject: [PATCH 22/24] Added video to readme Co-Authored-By: Joseph Hale <47901316+jhale1805@users.noreply.github.com> Co-Authored-By: Sai Nishanth Vaka Co-Authored-By: Rithvik Arun <43283635+rarun321@users.noreply.github.com> --- README.md | 5 +++++ data/README.md | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a865fbf..52824fa 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,9 @@ runtime. In order to make terminal output, you can input a command in this format when on the src\runtime: ``` node .\codeable_cli.js "../../data/fibonacci.code" +``` + +Video demonstration of the implementation +``` +https://youtu.be/ernDGFt_-Ms ``` \ No newline at end of file diff --git a/data/README.md b/data/README.md index b99c2ac..e3461e0 100644 --- a/data/README.md +++ b/data/README.md @@ -1,3 +1,7 @@ -This directory should contain at least 5 sample source programs in your -language. The sample programs should cover the constraints listed above -in the instructions. \ No newline at end of file +# Sample programs + +The `.code` files in this directory are sample programs that demonstrate the full feature set of Codeable. + +## `factorial.code` +Demonstrates the following requirements: + - \ No newline at end of file -- knotmirror 0.0.1 From da41abd1ed1846878dda5e7bae7d470e5a018a70 Mon Sep 17 00:00:00 2001 From: jgjanes <44354744+jgjanes@users.noreply.github.com> Date: Fri, 29 Apr 2022 10:34:41 -0700 Subject: [PATCH 23/24] Added main branch contributons --- doc/contribution.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/contribution.txt b/doc/contribution.txt index f431ead..87a14eb 100644 --- a/doc/contribution.txt +++ b/doc/contribution.txt @@ -9,3 +9,14 @@ | 2022-04-06 | @jgjanes | Jacob Janes | Finalized interpreter discussion for milestone 1 | | 2022-04-06 | @07sainishanth | Sai Nishanth Vaka | Verified grammar added final touches | | 2022-04-06 | @everyone | Everyone | Completed Milestone 1 PDF Draft | +| 2022-04-20 | @07sainishanth | Sai Nishanth Vaka | Intialised parser file | +| 2022-04-21 | @jgjanes | Jacob Janes | Added partial evaluator and parser logic | +| 2022-04-21 | @jgjanes | Jacob Janes | Update validation of boolean and term expression in parser | +| 2022-04-21 | @jgjanes | Jacob Janes | Updated parser and removed quotes for tokens | +| 2022-04-25 | @jakehresh | Jacob Hreshchyshyn | Added Logic for the for loops to grammar documentation | +| 2022-04-26 | @jgjanes | Jacob Janes | Create Browser Runtime Environment | +| 2022-04-26 | @rarun321 | Rithvik Arun | Create Browser Runtime Environment | +| 2022-04-26 | @jhale1805 | Joseph Hale | Create Browser Runtime Environment | +| 2022-04-26 | @jhale1805 | Joseph Hale | WIP Codeable improvements | +| 2022-04-26 | @jhale1805 | Joseph Hale | Successfully evaluate SER502 example language | +| 2022-04-26 | @jhale1805 | Joseph Hale | Move sample program to code textarea | -- knotmirror 0.0.1 From c6d7594e27ff88eaff0ac2b478c295e6e0ac3e24 Mon Sep 17 00:00:00 2001 From: jgjanes <44354744+jgjanes@users.noreply.github.com> Date: Fri, 29 Apr 2022 10:42:28 -0700 Subject: [PATCH 24/24] Added full contribution list for final language --- doc/contribution.txt | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/doc/contribution.txt b/doc/contribution.txt index 87a14eb..77389d8 100644 --- a/doc/contribution.txt +++ b/doc/contribution.txt @@ -20,3 +20,46 @@ | 2022-04-26 | @jhale1805 | Joseph Hale | WIP Codeable improvements | | 2022-04-26 | @jhale1805 | Joseph Hale | Successfully evaluate SER502 example language | | 2022-04-26 | @jhale1805 | Joseph Hale | Move sample program to code textarea | +| 2022-04-28 | @jhale1805 | Joseph Hale | Integreate parser/evaluator with IDE | +| 2022-04-28 | @jgjanes | Jacob Janes | Implement Strings & other parser improvements | +| 2022-04-28 | @rarun321 | Rithvik Arun | Implement Strings & other parser improvements | +| 2022-04-28 | @jhale1805 | Joseph Hale | Implement Strings & other parser improvements | +| 2022-04-28 | @jgjanes | Jacob Janes | Evaluate Codeable Quadratic Formula | +| 2022-04-28 | @rarun321 | Rithvik Arun | Evaluate Codeable Quadratic Formula | +| 2022-04-28 | @jhale1805 | Joseph Hale | Evaluate Codeable Quadratic Formula | +| 2022-04-28 | @jhale1805 | Joseph Hale | Clear Dead Code | +| 2022-04-28 | @jgjanes | Jacob Janes | Successfully evaluate factorial | +| 2022-04-28 | @rarun321 | Rithvik Arun | Successfully evaluate factorial | +| 2022-04-28 | @jhale1805 | Joseph Hale | Successfully evaluate factorial | +| 2022-04-28 | @07sainishanth | Sai Nishanth Vaka | Successfully evaluate factorial | +| 2022-04-28 | @jgjanes | Jacob Janes | Successfully evaluate fibonacci | +| 2022-04-28 | @rarun321 | Rithvik Arun | Successfully evaluate fibonacci | +| 2022-04-28 | @jhale1805 | Joseph Hale | Successfully evaluate fibonacci | +| 2022-04-28 | @jgjanes | Jacob Janes | Bug Fix Codeable | +| 2022-04-28 | @rarun321 | Rithvik Arun | Bug Fix Codeable | +| 2022-04-28 | @jhale1805 | Joseph Hale | Bug Fix Codeable | +| 2022-04-28 | @07sainishanth | Sai Nishanth Vaka | Bug Fix Codeable! | +| 2022-04-28 | @jgjanes | Jacob Janes | Add basic logic to for loops | +| 2022-04-28 | @rarun321 | Rithvik Arun | Add basic logic to for loops | +| 2022-04-28 | @jgjanes | Jacob Janes | Finalize Language | +| 2022-04-28 | @rarun321 | Rithvik Arun | Finalize Language | +| 2022-04-28 | @jhale1805 | Joseph Hale | Finalize Language | +| 2022-04-28 | @07sainishanth | Sai Nishanth Vaka | Finalize Language | +| 2022-04-28 | @jhale1805 | Joseph Hale | Adjust IDE environment in browser | +| 2022-04-28 | @07sainishanth | Sai Nishanth Vaka | Generate Terminal environment for codeable | +| 2022-04-28 | @jgjanes | Jacob Janes | Create Presentation | +| 2022-04-28 | @rarun321 | Rithvik Arun | Create Presentation | +| 2022-04-28 | @jhale1805 | Joseph Hale | Add strings to codeable variable tree | +| 2022-04-28 | @jhale1805 | Joseph Hale | Cleanup Dead code | +| 2022-04-28 | Everyone | Everyone | Record implementation video | +| 2022-04-29 | @jhale1805 | Joseph Hale | Update documentation | + + + + + + + + + +