Skip to content

Instantly share code, notes, and snippets.

@marekkowalczyk
Last active July 23, 2022 00:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marekkowalczyk/06eb0d7d850fd50497b0f65d350d0003 to your computer and use it in GitHub Desktop.
Save marekkowalczyk/06eb0d7d850fd50497b0f65d350d0003 to your computer and use it in GitHub Desktop.
Basic CLI RPN (Reverse Polish Notation) calculator in AWK
#! /usr/bin/awk -f
# Basic interactive CLI RPN (Reverse Polish Notation) calculator
# v1.1
# input: arithmetic expressions in RPN
# output: values of expressions
# Adapted by mko1971@gmail.com from Aho, Kernighan, and Weinberger, The AWK Programming Language, 143.
# 2021-01-26 CC0 1.0 Universal (CC0 1.0)
# https://gist.github.com/marekkowalczyk/06eb0d7d850fd50497b0f65d350d0003
BEGIN { printf "+ - * / ^\n'q' to quit and save last result to system clipboard\n'Q' to quit without saving\n\n"}
{ for ( i = 1; i <= NF; i++ )
if ( $i ~ /^[+-]?( [0-9]+[.]?[0-9]*|[.][0-9]+ )$/ ) { stack[++top] = $i }
else if ( $i == "+" && top > 1 ) { stack[top-1] += stack[top]; top-- }
else if ( $i == "-" && top > 1 ) { stack[top-1] -= stack[top]; top-- }
else if ( $i == "*" && top > 1 ) { stack[top-1] *= stack[top]; top-- }
else if ( $i == "/" && top > 1 ) { stack[top-1] /= stack[top]; top-- }
else if ( $i == "^" && top > 1 ) { stack[top-1] ^= stack[top]; top-- }
else if ( $i == "q" || $i == "quit" ) { command = "pbcopy"; print result | command; exit }
else if ( $i == "Q" || $i == "Quit" ) { exit }
else { printf( "\033[91mERROR: Unknown operator %s\033[39m\n", $i ); top = 0; next }
if ( top == 1 ) { result = stack[top--]; printf( "\033[4m%9.2f\033[0m\n\n", result ) }
else if ( top > 1 ) { printf( "\033[91mERROR: Too many operands\033[39m\n" ); top = 0 }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment