What's behind, shunting yard?There is no codebehind. It's just a few recursive algorithms implemented in 600 lines of JavaScript, you can see all by looking at the source code. Shunting Yard would be faster, but it would also be harder to implement. The difference isn't really visible on arithmetic expressions, which are always relatively short.
This is a useful thing!Yes. And C compilers are even more useful, for the same reason.
Please write something else for converting integer arithmetic expressionsThat wouldn't be easy. The algorithms I've made assume the existence of a stack (like the FPU-stack). I could make a stack of the general-purpose registers (eax,ebx,ecx,edx,edi,esi...), but that would be extremely inefficient. I could make a stack in RAM, but then it would be much like using a C compiler (it would be very hard to reassemble a program compiled for MacOS to run in DOS).
Comments in Slovenian?Close enough. They are in Croatian. Google Translate usually does a good job translating from Croatian to English.
The ExprTk library has the following capabilities:
Mathematical operators (+, -, *, /, %, ^)
Functions (min, max, avg, sum, abs, ceil, floor, round, roundn, exp, log, log10, logn, pow, root, sqrt, clamp, inrange, swap)
Trigonometry (sin, cos, tan, acos, asin, atan, atan2, cosh, cot, csc, sec, sinh, tanh, d2r, r2d, d2g, g2d, hyp)
Equalities & Inequalities (=, ==, <>, !=, <, <=, >, >=)
Assignment (:=, +=, -=, *=, /=, %=)
Logical operators (and, nand, nor, not, or, xor, xnor, mand, mor)
Control structures (if-then-else, ternary conditional, switch case, return-statement)
Loop structures (while loop, for loop, repeat until loop, break, continue)
Optimization of expressions (constant folding, strength reduction, operator coupling, special functions and dead code elimination)
String operations (equalities, inequalities, logical operators, concatenation and sub-ranges)
Expression local variables, vectors and strings
User defined variables, vectors, strings, constants and function support
Multivariate function composition
Multiple sequence point and sub expression support
Numeric integration and differentiation
Vector Processing: BLAS-L1 (axpy, axpby, axpb), all/any-true/false, count, rotate-left/right, shift-left/right, sort, nth_element, iota, sum, kahan-sum, dot-product, copy
File-IO package (routines include: open, close, read, write, getline, support for binary and text modes)
Support for various numeric types (float, double, long double, MPFR/GMP)
Single header implementation, no building required. No external dependencies.
Completely portable (Compiled and executed upon: x86 x86-64, ARMv7/8, POWER6/7 and AVR32)
sqrt(1 - (x^2))
clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1)
sin(2 * x)
if (((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z)
inrange(-2,m,+2) == (({-2 <= m} and [m <= +2]) ? 1 : 0)
({1 / 1} * [1 / 2] + (1 / 3)) - {1 / 4} ^ [1 / 5] + (1 / 6) -({1 / 7} + [1 / 8]*(1 / 9))
a * exp(2 * t) + c
z := x + sin(2 * pi / y)
2x + 3y + 4z + 5w == 2 * x + 3 * y + 4 * z + 5 * w
3(x + y) / 2 + 1 == 3 * (x + y) / 2 + 1
(x + y)3 + 1 / 4 == (x + y) * 3 + 1 / 4
(x + y)z + 1 / 2 == (x + y) * z + 1 / 2
(sin(x/pi)cos(2y) + 1)==(sin(x / pi) * cos(2 * y) + 1)
while(x <= 100) { x += 1; }
x <= 'abc123' and (y in ('AStr' + 'ing')) or ('1x2y3z' != z)
('REX' + x like '*123*') or ('a123b' ilike y)
When executed the output of the application would be something like:
[AST-INITIAL]
* [Binary]
* [Binary]
- [Unary]
- [Unary]
abs [Unary]
- [Binary]
* [Binary]
x
y
floor [Unary]
x
z
- [Binary]
12.900000
3.000000
[AST-FINAL]
* [Binary]
* [Binary]
abs [Unary]
- [Binary]
* [Binary]
x
y
floor [Unary]
x
z
9.900000
[ASSEMBLY]
L0: ; | ..
lea rax, [L2] ; 488D05........ | lea pConst, [L2] ..w
movsd xmm0, [rdx] ; F20F1002 | movsd v3, [pVariables] .r.w
mulsd xmm0, [rdx+8] ; F20F594208 | mulsd v3, [pVariables+8] .r.x
movsd xmm1, [rdx] ; F20F100A | movsd v4, [pVariables] .r..w
roundsd xmm1, xmm1, 9 ; 660F3A0BC909 | roundsd v4, v4, 9 ....x
subsd xmm0, xmm1 ; F20F5CC1 | subsd v3, v4 ...xR
xorpd xmm1, xmm1 ; 660F57C9 | xorpd v5, v5 .... w
subsd xmm1, xmm0 ; F20F5CC8 | subsd v5, v3 ...r x
maxsd xmm1, xmm0 ; F20F5FC8 | maxsd v5, v3 ...R x
mulsd xmm1, [rdx+16] ; F20F594A10 | mulsd v5, [pVariables+16] .R. x
mulsd xmm1, [rax] ; F20F5908 | mulsd v5, [pConst] . R x
movsd [rcx], xmm1 ; F20F1109 | movsd [pResult], v5 R R
L1: ; |
ret ; C3 |
.align 8
L2: ; |
.data CDCCCCCCCCCC2340
RESULT: -1885.514400
Overview
Supported data types: double, integer, complex, boolean, string, array
Extensible with custom operators (binary, infix or postfix)
Extensible with custom functions with an arbitrary number of function arguments
Support for an unlimited number of variables and constants
No limit on expression complexity
Reads binary, hexadecimal, complex, integer and string values from expressions and can be extended to read user defined values as well.
Supports a large variety of predefined operators, functions and constants.
Written in standard compliant C++ code with no external dependencies.
Features
By default the parser supports the following mathematical constants:
The eulerian number with: e = 2.718281828459045235360287
Pi with pi = 3.141592653589793238462643
The imaginary unit with: i = sqrt(-1)
Binary and ternary operators
Standard operators: +, -, *, /, ^
Assignment operators: =, +=, -=, *=, /=
Logical operators: and, or, xor, ==, !=, >, <, <=, >=
Bit manipulation: &, |, <<, >>
String concatenation: //
if then else conditionals with lazy evaluation: ?:
Postfix Operators
Unit postfixes (nano, micro, milli, kilo, giga, mega): n, mu, m, k, G, M
Transpose operator: '
Infix Operators
Sign operator and type conversions: -, (float), (int)
Special Operators
Multidimensional index operator: a[1,2]
Ternary if-then-else operator: (a<b) ? c:d
In-place array creation: {1,2,3}
Predefined Functions
Standard functions abs, sin, cos, tan, sinh, cosh, tanh, ln, log, log10, exp, sqrt
Unlimited number of arguments: min, max, sum
String functions: str2dbl, strlen, toupper
Complex functions: real, imag, conj, arg, norm
Array functions: sizeof, eye, ones, zeros
const size_t NN( N*N );
blaze::CompressedMatrix<double,rowMajor> A( NN, NN );
blaze::DynamicVector<double,columnVector> x( NN, 1.0 ), b( NN, 0.0 ), r( NN ), p( NN ), Ap( NN );
double alpha, beta, delta;
// ... Initializing the sparse matrix A
// Performing the CG algorithm
r = b - A * x;
p = r;
delta = (r,r);
for( size_t iteration=0UL; iteration<iterations; ++iteration )
{
Ap = A * p;
alpha = delta / (p,Ap);
x += alpha * p;
r -= alpha * Ap;
beta = (r,r);
if( std::sqrt( beta ) < 1E-8 ) break;
p = r + ( beta / delta ) * p;
delta = beta;
}
(echo (compile (parseArth (tokenizeArth "sqrt(a*a+b*b)"))))
would output something like:finit
fld dword [a]
fld dword [a]
fmulp st1,st0
fld dword [b]
fld dword [b]
fmulp st1,st0
faddp st1,st0
fsqrt
fstp dword [result]
Do you think that's a good idea? Right now, I don't know enough informatics to do it myself, and I don't have much time to learn that because I am already doing bad at school (and we don't even have informatics at school). If you think that's a good idea, I might do it after a few years.
It's not. My website sleeps from 22 to 23 PM UTC+1. If I want to make it accessible 24h/day, I'd have to pay for the hosting, and now it's free.Extreme poverty, people that can't pay a couple of dollars per month to have something fully functional, deserve my sympathy an I pray for them every night.
Internet even exist when I have 18. And in that case, no money to expend in it. :biggrin:No free lunches, though, except in Salvation Army. :t
Does anyone here happen to know the algorithms Emacs calculator uses?
As I've said, I am not a programmer. Can you break it down for me? Preferably in Croatian and using JavaScript to explain the code-related details. If you can't, then explain it in English and using some language similar to JavaScript (I think I would even be able to understand C++) to explain the code-related details.Does anyone here happen to know the algorithms Emacs calculator uses?
Aren't the sources of emacs calculator freely available? :idea:
So, if I understood you correctly, the assembly code my web-app produces can be compiled using not only FASM, but also using MASM? That's quite surprising.
Well, not all assemblers let you to use the syntax such as "st0" to access the stack (some require you to use the longer "ST(0)" format), and not all assemblers let you use a syntax such as "2f" to create 32-bit floats and use them as the arguments for "mov".
finit | finit |
fld dword [alpha] | fld alpha |
mov [result],57.2957795f | m2m result, FP4(57.2957795) |
fld dword [result] | fld dword ptr result |
fdivp st1, st0 | fdivp st(1), st |
fsin | fsin |
mov [result],2f | m2m result, FP4(2.) |
fld dword [result] | fld dword ptr result |
fxch | fxch |
fld1 | fld1 |
fxch | fxch |
fyl2x | fyl2x |
fldl2e | fldl2e |
fdivp st1, st0 | fdivp st(1), st |
fmulp st1, st0 | fmulp st(1), st |
fldl2e | fldl2e |
fmulp st1, st0 | fmulp st(1), st |
fld1 | fld1 |
fscale | fscale |
fxch | fxch |
fld1 | fld1 |
fxch | fxch |
fprem | fprem |
f2xm1 | f2xm1 |
faddp st1, st0 | faddp st(1), st |
fmulp st1, st0 | fmulp st(1), st |
fld dword [alpha] | fld alpha |
mov [result],57.2957795f | m2m result, FP4(57.2957795) |
fld dword [result] | fld result |
fdivp st1, st0 | fdivp st(1), st |
fcos | fcos |
mov [result],2f | m2m result, FP4(2.) |
fld dword [result] | fld result |
fxch | fxch |
fld1 | fld1 |
fxch | fxch |
fyl2x | fyl2x |
fldl2e | fldl2e |
fdivp st1, st0 | fdivp st(1), st |
fmulp st1, st0 | fmulp st(1), st |
fldl2e | fldl2e |
fmulp st1, st0 | fmulp st(1), st |
fld1 | fld1 |
fscale | fscale |
fxch | fxch |
fld1 | fld1 |
fxch | fxch |
fprem | fprem |
f2xm1 | f2xm1 |
faddp st1, st0 | faddp st(1), st |
fmulp st1, st0 | fmulp st(1), st |
faddp st1, st0 | faddp st(1), st |
mov [result],0f | mov result, 0 |
fld dword [result] | fld result |
fxch | fxch |
fsubp st1, st0 | fsubp st(1), st |
mov [result],0f | mov result, 0 |
fld dword [result] | fld result |
mov [result],1f | m2m result, FP4(1.) |
fld dword [result] | fld result |
fsubp st1, st0 | fsubp st(1), st |
fsubp st1, st0 | fsubp st(1), st |
fabs | fabs |
mov [result],1f | m2m result, FP4(1.) |
fld dword [result] | fld result |
mov [result],1000f | m2m result, FP4(1000.) |
fld dword [result] | fld result |
fdivp st1, st0 | fdivp st(1), st |
fcomip st1 | fcomip st, st(1) |
fstp dword [result] | fstp result |
jna l194549 | jna l194549 |
fld1 | fld1 |
jmp l876055 | jmp l876055 |
l194549: | l194549: |
fldz | fldz |
l876055: | l876055: |
mov [result],2f | m2m result, FP4(2.) |
fld dword [result] | fld result |
mov [result],2f | m2m result, FP4(2.) |
fld dword [result] | fld result |
faddp st1, st0 | faddp st(1), st |
mov [result],5f | m2m result, FP4(5.) |
fld dword [result] | fld result |
fcomip st1 | fcomip st, st(1) |
fstp dword [result] | fstp result |
jne l436047 | jne l436047 |
fld1 | fld1 |
jmp l71133 | jmp l71133 |
l436047: | l436047: |
fldz | fldz |
l71133: | l71133: |
mov [result],3f | m2m result, FP4(3.) |
fld dword [result] | fld result |
mov [result],1f | m2m result, FP4(1.) |
fld dword [result] | fld result |
faddp st1, st0 | faddp st(1), st |
mov [result],3.5f | m2m result, FP4(3.5) |
fld dword [result] | fld result |
fcomip st1 | fcomip st, st(1) |
fstp dword [result] | fstp result |
jnb l613334 | jnb l613334 |
fld1 | fld1 |
jmp l467593 | jmp l467593 |
l613334: | l613334: |
fldz | fldz |
l467593: | l467593: |
fistp dword [result] | fistp result |
mov eax,[result] | mov eax, result |
fistp dword [result] | fistp result |
or [result],eax | or result,eax |
fild dword [result] | fild result |
fistp dword [result] | fistp result |
mov eax,[result] | mov eax, result |
fistp dword [result] | fistp result |
and [result],eax | and result,eax |
fild dword [result] | fild result |
mov [result],45f | m2m result, FP4(45.) |
fld dword [result] | fld result |
fstp dword [result] | fstp result |
fld dword [result] | fld result |
fld1 | fld1 |
fld dword [result] | fld result |
fld dword [result] | fld result |
fmulp st1, st0 | fmulp st(1), st |
fsubp st1, st0 | fsubp st(1), st |
fsqrt | fsqrt |
fdivp st1, st0 | fdivp st(1), st |
fld1 | fld1 |
fpatan | fpatan |
mov [result],57.2957795f | m2m result, FP4(57.2957795) |
fld dword [result] | fld result |
fxch | fxch |
fmulp st1, st0 | fmulp st(1), st |
mov [result],0.5f | m2m result, FP4(0.5) |
fld dword [result] | fld result |
fsubp st1, st0 | fsubp st(1), st |
fabs | fabs |
mov [result],1f | m2m result, FP4(1.) |
fld dword [result] | fld result |
mov [result],1000f | m2m result, FP4(1000.) |
fld dword [result] | fld result |
fdivp st1, st0 | fdivp st(1), st |
fcomip st1 | fcomip st, st(1) |
fstp dword [result] | fstp result |
jna l606217 | jna l606217 |
fld1 | fld1 |
jmp l520364 | jmp l520364 |
l606217: | l606217: |
fldz | fldz |
l520364: | l520364: |
fld1 | fld1 |
fxch | fxch |
fsubp st1, st0 | fsubp st(1), st |
fistp dword [result] | fistp result |
mov eax,[result] | mov eax, result |
fistp dword [result] | fistp result |
and [result],eax | and result,eax |
fild dword [result] | fild result |
fstp dword [result] | fstp result |
So, nobody here uses EMACS? Well, to be honest, neither do I. I usually use "xed" on Mac and Notepad++ on PC.
Maybe you can modify mine (fork it) to produce MASM-compatible code?Sounds intriguing but right now I have absolutely no spare time...
BTW, I can't find out, what do "m2m" and "fp4" mean exactly in MASM?