Author Topic: Construct ?  (Read 425 times)

0 Members and 1 Guest are viewing this topic.

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1849
Re: Construct ?
« Reply #15 on: May 10, 2018, 01:26:33 PM »
Hi Aurel,

... stupid C constructs ...

They aren't stupid; in fact, they are simply much more flexible than a BASIC'er would ever expect.

Quote
so break should break loop like exit while or exit for ..right?

Yes:

... otherwise break (i.e. stop looping)

................

... the loop is going to break (it means the code will exit from the loop)

ok here is image:

It looks like porting should be pretty straight forward.

Regarding exit(0), older C compilers used to return a non-zero program termination code to the system on default upon successful completion even though their main() function was defined as void (i.e. a Sub). To signal a failure, the program was expected to return a zero program termination code via an explicit call to exit(0) anywhere in the program code.

The program termination codes are used for conditional branching in a batch file.


[UPD]

ExprEval.o2bas: Ported to classic BASIC syntax. Works with both console buffer and memory strings. Compiles successfully in JIT and 32-/64-bit static modes.

Code: OxygenBasic
  1. '****************************************
  2. ' EXPRESSION EVALUATOR - PC Magazine 1993
  3. '****************************************
  4.  
  5. #AUTODIM OFF
  6. #LOOKAHEAD
  7.  
  8. $FILENAME "ExprEval.exe"
  9. 'INCLUDE   "rtl32.inc"
  10. 'INCLUDE   "rtl64.inc"
  11. INCLUDE   "Console.inc"
  12.  
  13. INDEXBASE 0
  14.  
  15. DIM AS LONG   idx      = 0
  16. DIM AS LONG   contin   = TRUE
  17. DIM AS BYTE   NextChar
  18. DIM AS STRING Expr // ML: may come from memory, not only from console
  19.  
  20. Main
  21.  
  22. '***********************************************************
  23. '  GetNextChar - Reads chars until a non-space char is found
  24. '***********************************************************
  25. SUB GetNextChar()
  26.         DIM AS BYTE b AT STRPTR Expr
  27.  
  28.         DO
  29.                 NextChar = b[idx]
  30.                 idx++
  31.         LOOP WHILE NextChar AND (NextChar = 32 /*Asc("0")*/) // ML: memory overrun check added
  32. END SUB
  33.  
  34. '**************************************************************
  35. ' Expression - A recursive routine that evaluates an expression
  36. ' EXPRESSION = <EXPRESSION> + TERM | <EXPRESSION> - <TERM>
  37. '**************************************************************
  38. FUNCTION Expression() AS SINGLE
  39.         DIM AS SINGLE value = Term()
  40.  
  41.         DO
  42.                 SELECT NextChar
  43.                         CASE 32 // Asc(" ")
  44.                                 GetNextChar
  45.                         CASE 43 // Asc("+")
  46.                                 GetNextChar
  47.                                 value += Term()
  48.                         CASE 45 // Asc("-")
  49.                                 GetNextChar
  50.                                 value -= Term()
  51.                         CASE ELSE
  52.                                 RETURN value
  53.                 END SELECT
  54.         LOOP
  55. END FUNCTION
  56.  
  57. '************************************************************
  58. ' Term - Handles multiplication and division
  59. ' <TERM> = <TERM> * <FACTOR> | <TERM> div <FACTOR> | <FACTOR>
  60. '************************************************************
  61. FUNCTION Term() AS SINGLE
  62.         DIM AS SINGLE divisor, value = Factor()
  63.  
  64.         DO
  65.                 SELECT NextChar
  66.                         CASE 32 // Asc(" ")
  67.                                 GetNextChar
  68.                         CASE 42 // Asc("*")
  69.                                 GetNextChar
  70.                                 value *= Factor()
  71.                         CASE 94 // Asc("^")
  72.                                 GetNextChar
  73.                                 value = value ^ Factor() // ML: ^= isn't supported in O2
  74.                         CASE 47 // Asc("/")
  75.                                 GetNextChar
  76.                                 divisor = Factor()
  77.                                 IF divisor <> 0 THEN // ML: avoid O2-specific INFinities
  78.                                         value /= divisor
  79.                                 ELSE
  80.                                         PRINT "DIVISION BY ZERO" CR CR "Press any key to exit ..."
  81.                                         WAITKEY
  82.                                         TERMINATE
  83.                                 END IF
  84.                         CASE ELSE
  85.                                 RETURN value
  86.                 END SELECT
  87.         LOOP
  88. END FUNCTION
  89.  
  90. '**************************************************
  91. ' Factor - Handles numbers, minus signs and parens
  92. ' <FACTOR> = <EXPRESSION> | <VARIABLE> | <CONSTANT>
  93. '**************************************************
  94. FUNCTION Factor() AS SINGLE
  95.         DIM AS SINGLE value = 0
  96.         DIM AS LONG i, count = 0, d_point = FALSE
  97.         DIM AS BYTE b AT STRPTR Expr
  98.  
  99.         IF (NextChar <= 57 /*Asc("9")*/) AND (NextChar >= 48 /*Asc("0")*/) THEN
  100.                 WHILE (NextChar <= 57) AND (NextChar >= 48)
  101.                         value *= 10 + NextChar - 48 // Asc("0")
  102.                         NextChar = b[idx]
  103.                         idx++
  104.                         IF d_point THEN count++
  105.                         IF NextChar = 46 /*Asc(".")*/ THEN
  106.                                 NextChar = b[idx]
  107.                                 idx++
  108.                                 d_point = TRUE
  109.                         END IF
  110.                 WEND
  111.                 FOR i = 0 TO i < count
  112.                         value /= 10
  113.                 NEXT
  114.                 RETURN value
  115.         ELSE
  116.                 SELECT NextChar
  117.                         CASE 45 // Asc("-")
  118.                                 GetNextChar
  119.                                 RETURN -1 * Factor()
  120.                         CASE 40 // Asc("(")
  121.                                 GetNextChar
  122.                                 value = Expression()
  123.                                 IF NextChar <> 41 /*Asc(")")*/ THEN
  124.                                         PRINT "MISMATCHED PARENTHESES" CR CR "Press any key to exit ..."
  125.                                         WAITKEY
  126.                                         TERMINATE
  127.                                 ELSE
  128.                                         NextChar = b[idx]
  129.                                         idx++
  130.                                 END IF
  131.                                 RETURN value
  132.                         CASE 46 // Asc(".")
  133.                                 d_point = TRUE
  134.                         CASE ELSE
  135.                                 contin = FALSE
  136.                 END SELECT
  137.         END IF
  138.         RETURN 0
  139. END FUNCTION
  140.  
  141. '***************************
  142. ' Main - Program entry point
  143. '***************************
  144. SUB MAIN()
  145.         DIM AS SINGLE result
  146.  
  147.         SetConsoleTitle "Aurel's Expression Evaluator"
  148.  
  149.         PRINT "Expression must not contain any other symbol but:" CR
  150.         PRINT "'+'      addition" CR "'-'       subtraction" CR
  151.         PRINT "'*'      multiplication" CR "'/' division" CR
  152.         PRINT "'('      left parenthesis" CR "')'       right parenthesis" CR
  153.         PRINT "'.'      decimal point (must be preceded by digit)" CR
  154.         PRINT "'^'      x^y means x to the power of y" CR CR
  155.         PRINT "ENTER EXPRESSION:        "
  156.  
  157.         Expr = INPUT // ML: try e.g. "(1+2)*(6-3)" instead of INPUT
  158.         GetNextChar
  159.         result = Expression()
  160.  
  161.         IF ((NextChar = 13 /*console*/) OR (NextChar = 0 /*memory*/)) AND contin THEN
  162.                 PRINT "RESULT IS:               " STR(result, 3)
  163.         ELSE
  164.                 PRINT "SYNTAX ERROR"
  165.         END IF
  166.         PRINT CR CR "Press any key to exit ..."
  167.         WAITKEY
  168. END SUB

Enjoy! :)
« Last Edit: May 10, 2018, 06:33:13 PM by Mike Lobanovsky »
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, 2 x nVidia GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 3691
    • Oxygen Basic
Re: Construct ?
« Reply #16 on: May 11, 2018, 07:04:06 PM »
Many thanks, Mike.

May I include this example in the programming languages (projectsC) section?

PS:
I've remembered how to do this condition+assignment combo in o2, not that I would recommend it:

while ((a:=foo())<100)...

Code: [Select]
uses console
int foo(){ static int i : return i++}
int a
while ((a:=foo())<100){print a cr}
wait


Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1849
Re: Construct ?
« Reply #17 on: May 11, 2018, 09:54:06 PM »
Of course, Charles!

I think the PC Mag's Editorial Board wouldn't mind it either since their name is in its proper place in the code.

(Ah yes, I remember seeing a similar piece of code somewhere too now that you've mentioned it. But we already have lots of freedom of expression in Oxygen's looping constructs the way they are, so evidently I didn't pay much attention to yet one more of them. :) )
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, 2 x nVidia GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)

Aurel

  • Sr. Member
  • ****
  • Posts: 252
Re: Construct ?
« Reply #18 on: May 12, 2018, 01:30:05 AM »
Fine Mike..fine...  :)

my version will be little bit different  and without console.
Also i have one from Java which is more clear to me.

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1849
Re: Construct ?
« Reply #19 on: May 12, 2018, 04:12:14 AM »
No problem Aurel, do as you like.

What regards this evaluator, it can get rid of its console input too. The main() function code may include a loop e.g. to read Expr strings from a disk file sequentially line by line. The idx variable used to traverse the Expr string is global and thus can be reset to 0 for each new line in the file in each iteration of such loop. A few minor speedups can also be introduced and whole math/trig functions added. This way the evaluator can be turned into a tiny line-by-line interpreter of math-only input.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, 2 x nVidia GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)