Author Topic: Different approach for Commandline arguments  (Read 19719 times)

0 Members and 2 Guests are viewing this topic.

Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #45 on: June 13, 2015, 12:17:59 PM »
Hi John,

Bytecode compilation and execution is a form of interpretation. Direct interpretation is line-by-line parsing and execution based on in-place evaluation; this is how Eros says his thinBasic works. Bytecode requires precompilation of ultimately all tokens in the script into a binary tree of intermediate code that makes your "virtual machine" jump from one place to another following the already hard-wired program logic and execute utility routines that correspond to this or that high-level command. (please see Ed Davis' toy interpreter I ported to O2; it's a full-blown bytecode compilation and interpretation system)

Even though it's faster than direct interpretation, it's interpretation nonetheless and it is also slow as compared to low-level true machine code that a jitter generates. A bytecode compiler/interpreter would execute an entire subroutine to just add 1 and 1 together while machine code would execute just one CPU instruction, inc eax.

FBSL's bytecoded BASIC is the bottleneck of the entire system. There are even a couple cases when it falls back to direct interpretation when executing For, Do While/Until, and While commands (but not the code within the loops per se, which is bytecoded!). It will all be hopefully substituted with yet another JIT compiler -- BASIC jitter -- in FBSL v4. I mean, hopefully.

JRS

  • Guest
Re: Different approach for Commandline arguments
« Reply #46 on: June 13, 2015, 01:20:35 PM »
Sounds a bit like SB but more fine tuned for performance.

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #47 on: June 14, 2015, 07:02:29 AM »
Hi Charles,

I have finished rebuilding my little project. Using sysutil.inc saved about 50% of code to get the same results. Probably it could be done better, but I am pleased that I came so far.

SysUtil.inc, ParseUtil.inc and MinWin.inc provide many useful functions. It will be interesting to see them work in collaboration.

Roland

Code: OxygenBasic
  1. $ filename "TestArgs.exe"
  2. includepath "$/inc/"
  3. '#include "RTL32.inc"
  4. '#include "RTL64.inc"
  5.  
  6. include "sysutil.inc"
  7. include "console.inc"
  8.  
  9.  
  10. function exe_name() as string
  11.    zstring fname[512]
  12.    GetModuleFileName(NULL, fname, 512)
  13.    return fname
  14. end function
  15.  
  16. function app_path(string name) as string
  17.    zstring path[512]
  18.    sys fp
  19.    GetFullPathName(name, 512, path, @fp)
  20.    for x=len(path) to 1 step -1
  21.       if asc(path,x)=47 or asc(path,x)=92 then ' / or \
  22.         path=mid(path,1,x-1)
  23.          exit for
  24.       end if
  25.    next x
  26.    if x=0 then
  27.       path=CurDir()
  28.    end if
  29.    return path
  30. end function
  31.  
  32.  
  33. sub splitCommandLine(sys array, cnt, int limit)
  34.    
  35.    string arg at array
  36.    int ix at cnt
  37.    int idx
  38.    
  39.    ix=0 : idx=0
  40.    
  41.    if limit < 2 then
  42.       print "Error in splitCommandLine: limit < 2 "    
  43.       return
  44.    end if
  45.    
  46.    CreateArgV  ' arga=strings, argc=count, argv=block of string pointers
  47.   if argc<=limit then limit=argc
  48.    
  49.    ' build array of arg    
  50.   do
  51.      ix+=1: idx+=1    
  52.      arg[ix]=arga[idx]
  53.  
  54.      if ix=1 then
  55.         if mid(arg[1],-8) != "gxo2.exe"  _
  56.              and mid(arg[1],-7) != "co2.exe" _
  57.              and mid(arg[1],-4) != "gxo2" _
  58.              and mid(arg[1],-3) != "co2"  then
  59.  
  60.            'add placeholder
  61.           arg[2]=arg[1]
  62.            ix+=1
  63.         end if
  64.      end if
  65.      
  66.      if idx=limit then exit do    
  67.      
  68.    end do
  69.    
  70.    cnt=idx
  71.    
  72. end sub
  73.  
  74.  
  75. ' Test
  76. '====='
  77.  
  78. dim as string params[16]=""
  79. int count
  80.  
  81.    splitCommandLine(@params, @count, countof(params))
  82.  
  83.    print "This will only work with version A41 12/06/2015 and later" & cr & cr
  84.    print "Application's parameters:" & cr
  85.   for x=1 to count
  86.       print x ") "params[x] & cr
  87.    next x
  88.    print "count of parameters: " count & cr & cr
  89.    print "name of executable: " exe_name() & cr
  90.    print "path of executable: " ExeDir() & cr
  91.    print "path of application: " app_path(params[2]) & cr
  92.    print "current directory: "  CurDir() & cr & cr
  93.    if params[1]=params[2] then
  94.       print params[2] " is an executable" & cr
  95.    else
  96.       print params[2] " is executed with " exe_name() & cr
  97.    end if
  98.  
  99. print "Enter..." & cr
  100. waitkey()
  101.  

.

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #48 on: June 14, 2015, 05:43:17 PM »
Hi Roland,

Here is yet another approach, which is very economical, using only one dynamic string to hold the data block, and there are no parser dependencies :)

I will include it in SysUtil as a generic macro.

NB: When passing C-style argc,argv data, use byval.
f(argc, byval @argv)

Code: OxygenBasic
  1.   macro CreateArgBlock(argf,argn,args,argc,argv)
  2.   ==============================================
  3.   string args=argf  'buffer containing args
  4.  'literal argn max number of args    
  5.  sys    argv[argn]          'arg pointer table
  6.  sys    argc                'arg count
  7.  scope
  8.     indexbase 1
  9.     sys  na=1                'new arg flag
  10.    byte   b at strptr args  'source bytes
  11.    sys    i
  12.     while i<argn
  13.       select b
  14.       case 0       : exit while
  15.       case 1 to 32       : na=1 : b=0 'nullify spaces
  16.      case 34,39,44      : na=1 : b=0 'nullify quotes and commas
  17.      case else          : if na then argc++ : argv[argc]=@b : na=0 : i++
  18.       end select
  19.       @b++
  20.     wend
  21.   end scope
  22.   end macro
  23.   /*
  24.   'TEST
  25.  '====
  26.  '
  27.  CreateArgBlock "one, two, three four five",16,args,argc,argv
  28.   '
  29.  function f(sys argc,*argv) as sys
  30.   sys i
  31.   for i=1 to argc
  32.     char c at argv[i]
  33.     print i tab c cr
  34.   next
  35.   end function
  36.   '
  37.  f(argc,byval @argv)
  38.   */
  39.  

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #49 on: June 15, 2015, 05:57:22 AM »
Hi Charles,

my only real experience with Basic was GW-Basic some long time ago. So hopefully you will forgive me this question. Searching for byval and for byref I learned this: byval makes a copy of a variable, byref assigns an address of a variable. Is this true with Oxygenbasic too? Is this the same:

function func(int var1, double @var2) as int
function func(byval var1 as int, byref var2 as double) as int

Could I change var2 inside the function which would be visible outside of the function? I thought this would be possible only with subs. And is this the reason why you use: byval @argv ?


Roland

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #50 on: June 15, 2015, 06:50:19 AM »
Hi Roland,

byval / byref are used in basic-style prototypes but when byval is used before a call argument, it overrides the  prototype argument type, so you can pass any value directly. It often saves a lot of trouble :)

For instance, null is equivalent to byval 0

JRS

  • Guest
Re: Different approach for Commandline arguments
« Reply #51 on: June 15, 2015, 09:29:56 AM »
Quote
For instance, null is equivalent to byval 0

What is a NOT null?



Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #52 on: June 15, 2015, 10:51:23 AM »
Hi John,

not null will not compute but any sys integer value may be passed byval.

Aurel

  • Guest
Re: Different approach for Commandline arguments
« Reply #53 on: June 15, 2015, 02:04:22 PM »
HI Charles
looks like your macro
macro CreateArgBlock(argf,argn,args,argc,argv)
can be a good candidate for creating function in interpreter ?

JRS

  • Guest
Re: Different approach for Commandline arguments
« Reply #54 on: June 15, 2015, 06:01:28 PM »
Quote
not null will not compute

SB has ISDEF and ISUNDEF to deal with its null (uninitialized) variables.

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #55 on: June 16, 2015, 12:15:29 AM »
Aurel,

It has possibilities. Any application requiring read-only blocks of strings. So something similar could be used to pre-parse a script.

John,

#ifdef and #ifndef are available to test the existence of variables etc at compile time, though this is a different concept to null and byval n.

Prototypes may also specify optional arguments and arguments with default values:

function f( string s="abc", sys v=42)
 

JRS

  • Guest
Re: Different approach for Commandline arguments
« Reply #56 on: June 16, 2015, 12:26:08 AM »
Quote
Prototypes may also specify optional arguments and arguments with default values:

The default value feature is nice. With SB, I have to first test to see if the passed argument is undef then assign it a default value before proceeding.