Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
|
|
@ -0,0 +1,60 @@
|
|||
(require 'hash)
|
||||
(string-delimiter "")
|
||||
|
||||
(define (^ a b ) (expt a b)) ;; add this not-native function
|
||||
(define-syntax-rule (r-assoc? op) (= op "^"))
|
||||
(define-syntax-rule (l-assoc? op) (not ( = op "^" )))
|
||||
(define PRECEDENCES (list->hash
|
||||
'(("+" . 2) ("-" . 2) ("*" . 3) ("/" . 3) ("//" . 3) ("^" . 4))
|
||||
(make-hash)))
|
||||
|
||||
;; RPN vector or list -> infix tree -> (a op (b op c) d) ..
|
||||
(define (rpn->infix rpn)
|
||||
(define S (stack 'S))
|
||||
(for ((token rpn))
|
||||
(if (procedure? token)
|
||||
(let [(op2 (pop S)) (op1 (pop S))]
|
||||
(unless (and op1 op2) (error "cannot translate expression" rpn))
|
||||
(push S (list op1 token op2))
|
||||
)
|
||||
(push S token ))
|
||||
(writeln 'token (string token) 'stack (stack->list S)))
|
||||
(begin0
|
||||
(pop S) ;; return (top S)
|
||||
(unless (stack-empty? S) (error "ill-formed rpn" rpn)))
|
||||
)
|
||||
|
||||
;; a node tree is (left op right) or a number
|
||||
(define-syntax-id _.left (first _)) ; mynode.left expands to (first mynode)
|
||||
(define-syntax-id _.right (third _))
|
||||
(define-syntax-id _.op (string (second _ )))
|
||||
(define-syntax-rule (precedence node) (hash-ref PRECEDENCES (string (second node))))
|
||||
|
||||
(define (left-par? node) ; does lhs needs ( lhs ) ?
|
||||
(cond
|
||||
[(number? node.left) #f]
|
||||
[(< (precedence node.left) (precedence node)) #t]
|
||||
[(and
|
||||
(r-assoc? node.op)
|
||||
(= (precedence node.left) (precedence node))) #t]
|
||||
[else #f]))
|
||||
|
||||
(define (right-par? node)
|
||||
(cond
|
||||
[(number? node.right) #f]
|
||||
[(< (precedence node.right) (precedence node)) #t]
|
||||
[(and
|
||||
(l-assoc? node.op)
|
||||
(= (precedence node.right) (precedence node))) #t]
|
||||
[else #f]))
|
||||
|
||||
;; infix tree -> char string
|
||||
(define (infix->string node)
|
||||
(cond
|
||||
[(number? node) (string node)]
|
||||
[else (let
|
||||
[(lhs (infix->string node.left))
|
||||
(rhs (infix->string node.right))]
|
||||
(when (left-par? node) (set! lhs (string-append "(" lhs ")")))
|
||||
(when (right-par? node) (set! rhs (string-append "(" rhs ")")))
|
||||
(string-append lhs " " node.op " " rhs))]))
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import tables, strutils
|
||||
|
||||
const nPrec = 9
|
||||
|
||||
let ops: Table[string, tuple[prec: int, rAssoc: bool]] =
|
||||
{ "^": (4, true)
|
||||
, "*": (3, false)
|
||||
, "/": (3, false)
|
||||
, "+": (2, false)
|
||||
, "-": (2, false)
|
||||
}.toTable
|
||||
|
||||
proc parseRPN(e: string) =
|
||||
echo "postfix: ", e
|
||||
var stack = newSeq[tuple[prec: int, expr: string]]()
|
||||
|
||||
for tok in e.split:
|
||||
echo "Token: ", tok
|
||||
if ops.hasKey tok:
|
||||
let op = ops[tok]
|
||||
let rhs = stack.pop
|
||||
var lhs = stack.pop
|
||||
|
||||
if lhs.prec < op.prec or (lhs.prec == op.prec and op.rAssoc):
|
||||
lhs.expr = "(" & lhs.expr & ")"
|
||||
|
||||
lhs.expr.add " " & tok & " "
|
||||
|
||||
if rhs.prec < op.prec or (rhs.prec == op.prec and not op.rAssoc):
|
||||
lhs.expr.add "(" & rhs.expr & ")"
|
||||
else:
|
||||
lhs.expr.add rhs.expr
|
||||
|
||||
lhs.prec = op.prec
|
||||
stack.add lhs
|
||||
else:
|
||||
stack.add((nPrec, tok))
|
||||
|
||||
for f in stack:
|
||||
echo " ", f.prec, " ", f.expr
|
||||
|
||||
echo "infix: ", stack[0].expr
|
||||
|
||||
for test in ["3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"]:
|
||||
test.parseRPN
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
integer show_workings = 1
|
||||
|
||||
constant operators = {"^","*","/","+","-"},
|
||||
precedence = { 4, 3, 3, 2, 2 },
|
||||
rassoc = {'r', 0 ,'l', 0 ,'l'}
|
||||
|
||||
procedure parseRPN(string expr, string expected)
|
||||
sequence stack = {}
|
||||
sequence ops = split(expr)
|
||||
string lhs, rhs
|
||||
integer lprec,rprec
|
||||
printf(1,"Postfix input: %-30s%s", {expr,iff(show_workings?'\n':'\t')})
|
||||
if length(ops)=0 then ?"error" return end if
|
||||
for i=1 to length(ops) do
|
||||
string op = ops[i]
|
||||
integer k = find(op,operators)
|
||||
if k=0 then
|
||||
stack = append(stack,{9,op})
|
||||
else
|
||||
if length(stack)<2 then ?"error" return end if
|
||||
{rprec,rhs} = stack[$]; stack = stack[1..$-1]
|
||||
{lprec,lhs} = stack[$]
|
||||
integer prec = precedence[k]
|
||||
integer assoc = rassoc[k]
|
||||
if lprec<prec or (lprec=prec and assoc='r') then
|
||||
lhs = "("&lhs&")"
|
||||
end if
|
||||
if rprec<prec or (rprec=prec and assoc='l') then
|
||||
rhs = "("&rhs&")"
|
||||
end if
|
||||
stack[$] = {prec,lhs&" "&op&" "&rhs}
|
||||
end if
|
||||
if show_workings then
|
||||
?{op,stack}
|
||||
end if
|
||||
end for
|
||||
string res = stack[1][2]
|
||||
printf(1,"Infix result: %s [%s]\n", {res,iff(res=expected?"ok","**ERROR**")})
|
||||
end procedure
|
||||
|
||||
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")
|
||||
show_workings = 0
|
||||
parseRPN("1 2 + 3 4 + ^ 5 6 + ^","((1 + 2) ^ (3 + 4)) ^ (5 + 6)")
|
||||
parseRPN("1 2 + 3 4 + 5 6 + ^ ^","(1 + 2) ^ (3 + 4) ^ (5 + 6)")
|
||||
parseRPN("moon stars mud + * fire soup * ^","(moon * (stars + mud)) ^ (fire * soup)")
|
||||
parseRPN("3 4 ^ 2 9 ^ ^ 2 5 ^ ^","((3 ^ 4) ^ 2 ^ 9) ^ 2 ^ 5")
|
||||
parseRPN("5 6 * * + +","error")
|
||||
parseRPN("","error")
|
||||
parseRPN("1 4 + 5 3 + 2 3 * * *","(1 + 4) * (5 + 3) * 2 * 3")
|
||||
parseRPN("1 2 * 3 4 * *","1 * 2 * 3 * 4")
|
||||
parseRPN("1 2 + 3 4 + +","1 + 2 + 3 + 4")
|
||||
parseRPN("1 2 + 3 4 + ^","(1 + 2) ^ (3 + 4)")
|
||||
parseRPN("5 6 ^ 7 ^","(5 ^ 6) ^ 7")
|
||||
parseRPN("5 4 3 2 ^ ^ ^","5 ^ 4 ^ 3 ^ 2")
|
||||
parseRPN("1 2 3 + +","1 + 2 + 3")
|
||||
parseRPN("1 2 + 3 +","1 + 2 + 3")
|
||||
parseRPN("1 2 3 ^ ^","1 ^ 2 ^ 3")
|
||||
parseRPN("1 2 ^ 3 ^","(1 ^ 2) ^ 3")
|
||||
parseRPN("1 1 - 3 +","1 - 1 + 3")
|
||||
parseRPN("3 1 1 - +","3 + 1 - 1") -- [txr says 3 + (1 - 1)]
|
||||
parseRPN("1 2 3 + -","1 - (2 + 3)")
|
||||
parseRPN("4 3 2 + +","4 + 3 + 2")
|
||||
parseRPN("5 4 3 2 + + +","5 + 4 + 3 + 2")
|
||||
parseRPN("5 4 3 2 * * *","5 * 4 * 3 * 2")
|
||||
parseRPN("5 4 3 2 + - +","5 + 4 - (3 + 2)") -- [python says 5 + (4 - (3 + 2))]
|
||||
parseRPN("3 4 5 * -","3 - 4 * 5")
|
||||
parseRPN("3 4 5 - *","3 * (4 - 5)") -- [python says (3 - 4) * 5] [!!flagged!!]
|
||||
parseRPN("3 4 - 5 *","(3 - 4) * 5")
|
||||
parseRPN("4 2 * 1 5 - +","4 * 2 + 1 - 5") -- [python says 4 * 2 + (1 - 5)]
|
||||
parseRPN("4 2 * 1 5 - 2 ^ /","4 * 2 / (1 - 5) ^ 2")
|
||||
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
func p(pair, prec) {
|
||||
pair[0] < prec ? "( #{pair[1]} )" : pair[1];
|
||||
}
|
||||
|
||||
func rpm_to_infix(string) {
|
||||
say "#{'='*17}\n#{string}";
|
||||
var stack = [];
|
||||
string.each_word { |w|
|
||||
if (w ~~ /\d/) {
|
||||
stack << [9, w.to_f];
|
||||
}
|
||||
else {
|
||||
var y = stack.pop;
|
||||
var x = stack.pop;
|
||||
given(w) {
|
||||
when ('^') { stack << [4, [p(x,5), w, p(y,4)].join(' ')] }
|
||||
when (<* />) { stack << [3, [p(x,3), w, p(y,3)].join(' ')] }
|
||||
when (<+ ->) { stack << [2, [p(x,2), w, p(y,2)].join(' ')] }
|
||||
}
|
||||
say stack;
|
||||
}
|
||||
};
|
||||
'-'*17 -> say;
|
||||
stack.map{_[1]};
|
||||
}
|
||||
|
||||
var tests = [
|
||||
'3 4 2 * 1 5 - 2 3 ^ ^ / +',
|
||||
'1 2 + 3 4 + ^ 5 6 + ^',
|
||||
];
|
||||
|
||||
tests.each { say rpm_to_infix(_).join(' ') }
|
||||
Loading…
Add table
Add a link
Reference in a new issue