I've got tons of homegrown database code from the 1980's - from an old VAX/VMS minicomputer. We actually "implemented" a SIGMA function to loop through data manipulations! I've posted some snippets and attached two of the whole code files.
Any value posting the whole set of code here? I've seen people discuss developing parsers and there own language - this is one as an example.
Some of the upper level NON-MATH functions
Code:
New EQ Functions 01-Sep-1993
------------------
OPEN(open_opt%,dt_cnct_prefix$,open_acc%,open_all%,open_span%
,open_filesize%,open_extend%,open_file$,open_dcr$)
FIELD(dt_prefix$,field_opt%,field%,element%,format_opt%)
CONVERT(dt_prefix$,cnv_opt%,cnv_what?)
CNF(cnf_chnl%,cnf_file$)
DATE(in_type%,out_type%,in_date$)
NUMBER(out_len%,in_num$,out_format%)
INFO(info_what%)
MAIL(who$,subj$,text$)
RANDOM
DAY(date_typ%,date$)
IDENT(identifier$)
SIGMA$(loop_vbl,loop_start%,loop_end%,loop_step%,loop_expression$)
SET(set_opt%,set_extra%,set_text$)
ERROR(err_opt%,text$)
PUT(row%,col%,put_opt%,text$)
TYPE(typ_key$,typ_desc$,typ_master$,typ_primary$,typ_key%,typ_first$
,typ_last$,typ_read_crit$,typ_write_crit$
{{,typ_anc_file$,typ_key_field$,typ_key%}...})
PARAM(param_slot%,param_string$)
ABORT
END
EQLOADRTL.BAS - loads the runtime library!
Code:
1 FUNCTION LONG EQ_LOAD_RTL( LONG A_CHAN) &
&
! &
! Product : Equation Functions &
! Program : EQLOADRTL.BAS &
! Author : Stephen Zlamany &
! Date : May 1, 1989 &
! &
! ANTARES Computing Systems, Inc. &
! 19 Ripton Road, Huntington, CT &
! &
10 %INCLUDE "ACS$INC:ACSDEFS.INC"
%INCLUDE "ACS$INC:EQDEFS.INC"
100 EXTERNAL LONG FUNCTION LIB$GET_VM
EXTERNAL LONG CONSTANT SS$_NORMAL
DECLARE LONG E_CHAN &
,E_OPC_CHAN
900 WHEN ERROR USE ERROR_HANDLER
1000 ! Start of Main Code
BEGIN:
CALL PEEK_L(A_CHAN,ACS$A_CHAN,A.CHAN%)
IF A_CHAN <> A.CHAN% THEN
! Error condition
END IF
CALL PEEK_L(A_CHAN,ACS$E_CHAN,E_CHAN)
CALL PEEK_W(E_CHAN,EQP$OPC_FLAG,E.FLAG%)
IF E.FLAG% <> -1% THEN
! Error condition
END IF
CALL PEEK_L(E_CHAN,EQP$OPC_ADDR,E_OPC_CHAN)
GOSUB LOAD_OPC
GOSUB SORT_OPC
OPR_INIT = -1%
GOTO RTN_CALLER
1100 ! Load opcodes
LOAD_OPC:
OPC.CNT% = 1%
CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"* ")
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX &
OR EQT$OPR_NUMERIC)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,3%)
OPC.CNT% = OPC.CNT% + 1%
CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"+ ")
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX &
OR EQT$OPR_NUMERIC)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,4%)
OPC.CNT% = OPC.CNT% + 1%
CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"+ ")
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,1%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_UNARY &
OR EQT$OPR_NUMERIC)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,2%)
CALL POKE_W(E_OPC_CHAN,EQP$OPC_UNARY_PLUS,OPC.CNT%)
OPC.CNT% = OPC.CNT% + 1%
CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"- ")
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX &
OR EQT$OPR_NUMERIC)
CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,4%)
OPC.CNT% = OPC.CNT% + 1%
and EQEXECUTE.MAR (written in machine code!).
Code:
.title EQ_EXECUTE
.sbttl Program Heading
.ident /V1.0/
;
;
; Product : Equation Functions
; Program : EQEXECUTE.MAR
; Date : March 22, 1989
;
; ANTARES Computing Systems, Inc.
; 19 Ripton Road, Huntington, CT
;
;
.page
.sbttl MACRO definitions
;
; RPN Opcode block macros
;
.macro opstart sel,base,limit
caseb sel,base,limit
op_start = .
op_ptr = .
limit_l = %length(limit)-1
.blkw %extract(1,limit_l,limit)
.endm
.macro opcd num
.if nb num
num.1 = num
.iff
num.1 = 1
.endc
.rept num.1
op_save = .
. = op_ptr
.word op_save - op_start
op_ptr = .
. = op_save
.endr
.endm
.macro opend
op_ptr = 0
op_end = 0
.endm
;
; RPN word type case macro (literal, variable or operator)
;
.macro rinit sel,limit
caseb sel,#0,limit
rtype_start= .
limit_l = %length(limit)-1
.word <%extract(2,limit_l,limit)*2>+2
tmp_limit = .
.blkw %extract(2,limit_l,limit)
rtype_limit = <.-tmp_limit>/2
.endm
.macro rtype bits
rtype_save = .
. = rtype_start
tmp = 0
.rept <rtype_limit+1>
.if ne <bits & tmp>
.word rtype_save - rtype_start
.iff
. = . + 2
.endc
tmp = <tmp + 1>
.endr
. = rtype_save
.endm
.page
.sbttl Data Area (protected)
.psect eq_data,nowrt,noexe,shr,pic,con,long
;
; Definitions
;
arg_achan = 1 * 4 ; A_CHAN
arg_option = 2 * 4 ; options
arg_object = 3 * 4 ; object string
arg_prec = 4 * 4 ; precision
arg_string = 5 * 4 ; result string
arg_value = 6 * 4 ; result value
arg_result = 7 * 4 ; result type
;
; DT offsets and constants
;
d_chan = 8 ; D_CHAN within A_CHAN
dc_flag = 0 ; D_CHAN flag
dc_workmap = 2 ; D_CHAN work map flag
dc_workaddr = 4 ; D_CHAN work map address
dc_recurse = 8 ; D_CHAN recursion count
dc_count = 10 ; D_CHAN slot count
dc_slots = 12 ; D_CHAN slot pool
dp_flag = 0 ; DS_CHAN flag
dp_prefix = 8 ; DS_CHAN prefix
;
dts$normal = 0
dts$stk_ovr = 36
dts$sub_ovr = 55
dts$udef_sym = 75
dts$not_yet_imp = 250
dts$bad_addr = -21
dts$ext_noopn = -121
dts$inv_ste = -131
dts$inv_obj = -132
;
; EQ offsets and constants
;
obj_hdr_loff = 12
obj_hdr_coff = 14
obj_hdr_doff = 16
obj_hdr_ver = 20
;
eq_ver = 5
;
rpn_oper = 256
rpn_lit = 512
rpn_var = 1024
;
lit_byte = 256
lit_word = 512
lit_long = 1024
;
stb_start = 26
stb_len = 26
stb_namptr = 0
stb_namlen = 2
stb_flg = 4
stb_fld = 6
stb_slot = 8
stb_addr = 12
stb_bd0 = 20
stb_bd1 = 22
stb_bd2 = 24
;
ste_sub = 3
ste_sub1 = 1
ste_sub2 = 2
ste_byte = 4
ste_word = 8
ste_long = 16
ste_scalar = 32
ste_def = 64
ste_zhh = 128
ste_icnt = 256
ste_dcr = 512
;
; Miscellaneous options and values
;
blank_dsc: .word 0 ; no length
.byte dsc$k_dtype_t ; text string
.byte dsc$k_class_d ; dynamic string
blank_str: .word 0 ; no length
.byte dsc$k_dtype_t ; text string
.byte dsc$k_class_d ; dynamic string
.long 0 ; no address
null_str: .ascid // ; Null string
zero_str: .ascid /0/ ; Zero value string
.align long ; get on a longword boundary
inf$username: .long 1 ; GET_INFO option
inf$uic: .long 2 ; GET_INFO option
frm$sto: .long 1 ; Format STO
frm$inp: .long 2 ; Format INP
frm$srt: .long 3 ; Format SRT
frm$dsp: .long 4 ; Format DSP
val$0: .long 0 ; general option value
val$1: .long 1 ; general option value
val$2: .long 2 ; general option value
val$3: .long 3 ; general option value
val$4: .long 4 ; general option value
val$5: .long 5 ; general option value
val$6: .long 6 ; general option value
dto$field: .long <1@0>+<1@11>
dto$name: .long <1@1>+<1@11>
dto$fld_noerr: .long <1@0>+<1@11>+<1@15>
dto$name_noerr: .long <1@1>+<1@11>+<1@15>
dto$get: .long <1@2>+<1@11>
dto$table: .long <1@4>+<1@11>
dto$tb_init: .long <1@4>+<1@7>+<1@11>
dto$tb_fnd_get: .long <1@4>+<1@2>+<1@8>+<1@11>
dto$init: .long <1@7>+<1@11>
dto$find: .long <1@8>+<1@11>
dto$no_wrk_map: .long <1@11>
dto$no_error: .long <1@15>
eqo$value: .long <1@22>
eqo$string: .long <1@23>
eqo$either: .long <1@22>+<1@23>
;
; Stack Work Space
;
op_max = 6 ; Maximum number of operands
op_size = 9 ; Size of each operand block
ib_max = 4 ; Max number of iterative blocks
ib_size = 9 ; size of each iterative block
stack_size = <op_max*op_size>+<ib_max*ib_size>+16
obo_start = 16+<ib_max*ib_size>
obo_type = 0 ; Offset to type byte
obo_str = 1 ; Offset to Descriptor
obo_long = 1 ; Offset to longword value
obo_arg1 = obo_start ; Arguments
obo_arg2 = obo_arg1+op_size
obo_arg3 = obo_arg2+op_size
obo_arg4 = obo_arg3+op_size
obo_arg5 = obo_arg4+op_size
obo_arg6 = obo_arg5+op_size
obo_int1 = obo_arg1+obo_long
obo_int2 = obo_arg2+obo_long
obo_int3 = obo_arg3+obo_long
obo_int4 = obo_arg4+obo_long
obo_int5 = obo_arg5+obo_long
obo_int6 = obo_arg6+obo_long
obo_str1 = obo_arg1+obo_str
obo_str2 = obo_arg2+obo_str
obo_str3 = obo_arg3+obo_str
obo_str4 = obo_arg4+obo_str
obo_str5 = obo_arg5+obo_str
obo_str6 = obo_arg6+obo_str
obo_tmp1 = obo_start+1 ; STE address, subscript value
obo_tmp2 = obo_tmp1+4 ; Subscript value, index
obo_tmp3 = obo_tmp2+5 ; Index offset
obo_tmp4 = obo_tmp3+4 ; Array bound
;
; Operand Types
;
opt_long = 1 ; long
opt_str = 2 ; string
opt_either = 3 ; either type
opt_dyn = 4 ; dynamic bit
opt_strdyn = 6 ; dynamic string
opt_valerr = 8 ; value error
;
; Temporaries for op_get
;
opg_get = 8 ; operands to get
opg_got = 12 ; operands gotten
;
; Iteration Work Space
;
ibo_start = 16 ; Start
ibo_type = 0 ; Type offset
ibo_long = 1 ; Long offset
ibo_float = 1 ; D-Float offset
;
ibt_long = 1 ; Iteration index - long
ibt_float = 2 ; Iteration index - D-float
;
ifo_blk = 0 ; Number
ifo_bpc = 4 ; PC
ifo_spc = 8 ; Saved PC
ifo_sum = 12 ; Sum
ifo_end = 20 ; End value - D-float
ifo_step = 28 ; Step value - D-float
.page
.sbttl EQ_EXECUTE code - setup registers
.psect eq_execute,nowrt,exe,shr,pic,con
.entry eq_execute,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
;
; Register Use
;
; r2 - temporary
; r3 - temporary, used for A_CHAN
; r4 - RPN code PC
; r5 - Address of literal pool
; r6 - Address of literal blocks
; r7 - temporary
; r8 - Address of object
; r9 - pointer to Stack Work space
;
cmpw @arg_object(ap),#26 ; is object size of header
blss 10$ ; no - branch
movaq @arg_string(ap),r0 ; address of return string
movaq null_str,r1 ; address of null string
jsb g^str$copy_dx_r8 ; copy string
clrl @arg_value(ap) ; clear return value
clrl @arg_result(ap) ; clear result type
movaq @arg_object(ap),r8 ; address of object
movab @4(r8),r8 ; address of object data
cmpw obj_hdr_ver(r8),#eq_ver ; compare version
beql 20$ ; same - branch
10$: movl #dts$inv_obj,r0 ; otherwise, bad object
ret ; return
20$: moval err_handler,(fp) ; frame up the err_handler
subl2 #stack_size,sp ; push size of work space
movq blank_str,-(sp) ; push a blank string
movl sp,r9 ; pointer to temporary storage
movzwl obj_hdr_coff(r8),r4 ; offset to rpn pool
movzwl obj_hdr_doff(r8),r5 ; offset to literal pool
movzwl obj_hdr_loff(r8),r6 ; offset to lte's
addl2 r8,r4 ; add address to rpn
addl2 r8,r5 ; add address to literal
addl2 r8,r6 ; add address to lte's
decl r5 ; adjust literal
subl2 #4,r6 ; adjust lte's
.page
.sbttl Execute a word of RPN
;
; Here we loop through RPN words - executing each
;
rpnexe: cmpl r4,r5 ; still more rpn code
bgtru 30$ ; no - branch
movzwl (r4)+,r7 ; get RPN word
extzv #8,#3,r7,r1 ; get flags
rinit r1,#07 ; rpn init macro based on RPN word type
movl #dts$not_yet_imp,r0 ; give error
ret ; return
;
; We are now done - lets write out our results
;
30$: clrl r0 ; Get one operand
mcoml l^eqo$either,r1 ; Create a mask of both bits
bicl3 r1,@arg_option(ap),r1 ; Pass options through mask
divl2 l^eqo$value,r1 ; Shift down to bits 0 and 1
movab obo_start(r9),r7 ; Placing at start
jsb op_get ; Get operand(s)
bitb #opt_str,(r7) ; Is it string
beql 50$ ; No - branch
pushaq obo_str(r7) ; Get address of operand
pushaq @arg_string(ap) ; Get address of return string
calls #2,g^str$copy_dx ; Call STRING Copy
movl #opt_str,@arg_result(ap); Pass back result type
mull2 l^eqo$value,@arg_result(ap)
; Shift up to actual bits
bitb #opt_dyn,(r7) ; Is it dynamic string
beql 40$ ; No - branch
moval obo_str(r7),r0 ; Get address of operand
jsb g^str$free1_dx_r4 ; Call STRING Free
40$: clrl r0 ; Set status to success
ret ; Return
50$: movl obo_long(r7),@arg_value(ap)
; Copy into return value
movl #opt_long,@arg_result(ap)
; Pass back result type
mull2 l^eqo$value,@arg_result(ap)
; Shift up to actual bits
clrl r0 ; Set status to success
ret ; Return
.page
.sbttl Execute Literals
;
; RPN literals
;
rtype rpn_lit/256 ; Handle literals
bicw2 #rpn_lit,r7 ; Clear flag
movl (r6)[r7],r1 ; Address of LTE
movzwl r1,r0 ; Offset to data
addl2 r5,r0 ; Address of data
extzv #16,#12,r1,r1 ; Length of data
bitw #lit_byte,r1 ; Is it a byte
beql 60$ ; No - branch
cvtbl (r0),-(sp) ; Put it on the stack
movb #opt_long,-(sp) ; Push long type
The DO_SIGMA block of machine code!
Code:
do_sigma:
opcd ; Op-code 24, "SIGMA"
movzbl (sp)+,(r9) ; Get type off stack
movl (sp)+,(r9) ; Get address off stack
movl #3,r0 ; Get three operands
movl #opt_either,r1 ; Get either
movab obo_arg3(r9),r7 ; Placing at argument 3
jsb op_get ; Get operand(s)
movzbl (sp)+,r0 ; Get iterative count type
bitb #opt_long,r0 ; Is it long
bneq 440$ ; Yes - branch
pushr #^m<r0,r1,r4> ; Save some registers
moval 12(sp),r0 ; Address of string
jsb g^str$free1_dx_r4 ; Free up string
popr #^m<r0,r1,r4> ; Restore some registers
clrl (sp)+ ; Clear first part of string
440$: clrl (sp)+ ; Clear second part or long value
subl2 #36,sp ; Put iterative work space on stack
ashl #-4,r0,r0 ; Get iterative counter
mull2 #ib_size,r0 ; Make it an offset
moval ibo_start(r9),r7 ; Get address
addl2 r0,r7 ; Get iterative address
movl r7,(sp) ; Put it on the stack
movl (r9),ifo_bpc(sp) ; Set iterative PC
movl r4,ifo_spc(sp) ; Save current RPN PC
bitb #opt_long,r1 ; Is it long
beql 510$ ; No - branch
clrl ifo_sum(sp) ; Clear sum
movl obo_int1(r9),ibo_long(r7)
; Set start value
movl obo_int2(r9),ifo_end(sp); Set end value
movb #ibt_long,(r7) ; Set type
movl obo_int3(r9),ifo_step(sp)
; Set step - is it negative
bleq 450$ ; Yes - branch
cmpl ibo_long(r7),ifo_end(sp); Are we done already
brb 460$ ; Jump to check
450$: cmpl ifo_end(sp),ibo_long(r7); Are we done already
460$: bgtr 500$ ; Yes - branch
470$: movl ifo_bpc(sp),r4 ; Get iterative PC
jsb rpnexe ; Execute it
clrl r0 ; Get one operand
movl #opt_long,r1 ; Get long
movab obo_arg1(r9),r7 ; Placing at argument 1
jsb op_get ; Get operand(s)
addl2 obo_int1(r9),ifo_sum(sp); Sum the result
movl (sp),r7 ; Get iterative address
addl2 ifo_step(sp),ibo_long(r7)
; Increment counter
tstl ifo_step(sp) ; Are we a negative step
bleq 480$ ; Yes - branch
cmpl ibo_long(r7),ifo_end(sp); Are we done already
brb 490$ ; Jump to check
480$: cmpl ifo_end(sp),ibo_long(r7); Are we done already
490$: bleq 470$ ; No - branch
500$: movl ifo_spc(sp),r4 ; Restore RPN PC
movl ifo_sum(sp),r0 ; Save sum'd value
addl2 #36,sp ; Remove iterative work space
pushl r0 ; Push sum'd value
movb #opt_long,-(sp) ; Push long type
brw rpnexe ; Next RPN
510$: ; Handle float iteration
clrd ifo_sum(sp) ; Clear sum
pushal obo_str1(r9) ; Push operand 1
calls #1,g^bas$val_d ; Call VAL()
movd r0,ibo_long(r7) ; Set start value
pushal obo_str2(r9) ; Push operand 2
calls #1,g^bas$val_d ; Call VAL()
movd r0,ifo_end(sp) ; Set end value
movb #ibt_float,(r7) ; Set type
pushal obo_str3(r9) ; Push operand 3
calls #1,g^bas$val_d ; Call VAL()
movd r0,ifo_step(sp) ; Set step
pushr #^m<r7> ; Save r7
movl #3,r7 ; 3 possible operands
jsb op_free ; Free operands
popr #^m<r7> ; Restore r7
tstd ifo_step(sp) ; Is step negative
bleq 520$ ; Yes - branch
cmpd ibo_long(r7),ifo_end(sp); Are we done already
brb 530$ ; Jump to check
520$: cmpd ifo_end(sp),ibo_long(r7); Are we done already
530$: bgtr 570$ ; Yes - branch
540$: movl ifo_bpc(sp),r4 ; Get iterative PC
jsb rpnexe ; Execure it
clrl r0 ; Get one operand
movl #opt_str,r1 ; Get string
movab obo_arg1(r9),r7 ; Placing at argument 1
jsb op_get ; Get operand(s)
pushal obo_str1(r9) ; Push operand 1
calls #1,g^bas$val_d ; Call VAL()
addd2 r0,ifo_sum(sp) ; Sum the result
movl #1,r7 ; 1 possible operand
jsb op_free ; Free operands
movl (sp),r7 ; Get iterative address
addd2 ifo_step(sp),ibo_long(r7)
; Increment counter
tstd ifo_step(sp) ; Are we a negative step
bleq 550$ ; Yes - branch
cmpd ibo_long(r7),ifo_end(sp); Are we done already
brb 560$ ; Jump to check
550$: cmpd ifo_end(sp),ibo_long(r7); Are we done already
560$: bleq 540$ ; No - branch
570$: movl ifo_spc(sp),r4 ; Restore RPN PC
movd ifo_sum(sp),r0 ; Save sum'd value
addl2 #36,sp ; Remove iterative work space
movq blank_str,-(sp) ; Push a blank string
movd r0,-(sp) ; Push sum'd value
pushal 8(sp) ; Push result address
calls #3,g^bas$num1_d ; Call NUM1()
movb #opt_strdyn,-(sp) ; Push temporary string type
brw rpnexe ; Next RPN
do_xor:
opcd ; Op-code 25, "XOR"
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
Looks very familiar. The .MAR file is Vax assembly code. Feel free to post more as far as I am concerned. At least it will continue to exist as long as vbForums does.
By the power invested in me, all the threads I start are Niya and Olaf free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
Looks very familiar. The .MAR file is Vax assembly code. Feel free to post more as far as I am concerned. At least it will continue to exist as long as vbForums does.
Yes - VAX Assembly code - good times! Those are great memories in that code there for me! I can't believe I "commented" code lines at that level of detail.
I called it machine code to make it slightly more understandable to the group here - it was a direct implementation of the VAX instruction set architecture - I recall having a little pocket guide for those VAX opcodes.
I will definitely post more code. I'm about to embark on writing a parser and compiler for a database project I'm trying to get off the ground. Looking at this old code was to get those gears back in drive!
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
Didn't you pretty much HAVE to comment code to that level? My understanding was that Assembly was always 1:1 code to comments. The comments in the earlier code aren't as extensive, and aren't quite as useful, but then again, they don't need to be, either.
Didn't you pretty much HAVE to comment code to that level? My understanding was that Assembly was always 1:1 code to comments. The comments in the earlier code aren't as extensive, and aren't quite as useful, but then again, they don't need to be, either.
I totally agree with you - I can see that without those comments that just keeping track of trivial register usage from spot to spot hard to track. But really - I didn't even abbreviate - using the King's English for gods sake, lol! I don't speak that well in person these days!
But to counter that, I find that when JavaScript coding - where you have lots of deep levels of objects and what not driving classes and functions - should require the same level of comments. I find that I put ZERO comments in that code and instead rely on active coding with a debugger showing scope, and using the "code-a-bit-and-test-and-review-scope-values" to be the new norm for me.
I used to comment VB code back in those decades as well, sometimes writing paragraphs on the travails of coding for more hours a day then you should.
For example - I just wrote this code and it's got zero comments. Some of the variable are descriptive - so it's got that natural verbosity. Otherwise, I find zero ROI lately with any additional comments. If I come back to this code - I run a few examples through to re-familiarize myself, and hack and slay new code into place.
FWIW, this code below is taking a stored procedure that returns several SELECT statements - already turned into an ARRAY of JS OBJECTS - and discarding those that are meta-data (some of the meta data was using to HIDE columns in VB6 - those ELEMENTS are "deleted" from the ARRAY of JS OBJECTS), and otherwise taking the first SELECT ARRAY and making sure it's got enough EXTRA COLUMNS to have the subsequent SELECT ARRAY's merged into it. With each of those sequentent arrays re-written with OBJECTS for each row that have ELEMENT names changed to match the first SELECT's FIELD NAMES. Lots of this rows columns names moved up and down and what not. It needed 100% accuracy in debugging more that commenting for future assist.
Code:
var i_cleanup_form_display = function (objReturn, objFormInfo) {
var blnMetaRow = false;
var blnGridRow = false;
var blnGridMetaRow = false;
var strGridName = "";
var strLastGridName = "";
var intGridStart = 0;
var intGridEnd = 0;
var intFormColCount = 0;
var intFormColShort = 0;
var intColCount = 0;
var strHideCol = "";
var objNewRow = {};
var strNewCol = "";
var intCP = 0;
objFormInfo.active = true;
objFormInfo.arrForm = [];
objFormInfo.arrCols = [];
objFormInfo.arrGrid = [];
objFormInfo.objGrid = {};
for (var i = 0; i < objReturn.length; i++) {
blnMetaRow = false;
blnGridMetaRow = false;
if (!(typeof objReturn[i]["FrmToken"] == "undefined")) {
objFormInfo.arrForm.push({ "token": objReturn[i]["FrmToken"].substr(3), "text": objReturn[i]["FrmText"], "width": parseInt(objReturn[i]["FrmWidth"], 10) });
blnMetaRow = true;
}
if (!blnMetaRow) {
for (var propertyName in objReturn[i]) {
if (!(objReturn[0][propertyName] instanceof Function)) {
if ((propertyName.length >= 4) && (propertyName.substr(0, 4) == "~grd")) {
strGridName = propertyName;
blnGridRow = true;
break;
}
if ((propertyName.length >= 4) && (propertyName.substr(0, 4) == "~col")) {
blnGridMetaRow = true;
break;
}
}
}
if (blnGridRow) {
if (!(strGridName == strLastGridName)) {
objFormInfo.arrGrid.push({ "gridName": strGridName });
intGridStart = i;
strLastGridName = strGridName;
}
}
if (blnGridMetaRow) {
objFormInfo.objGrid[strGridName] = { "gridStart": intGridStart, "gridEnd": i - 1, "colInfo": objReturn[i] };
blnMetaRow = true;
}
}
if (blnMetaRow) {
objReturn.splice(i, 1);
i--;
}
}
intFormColCount = 0;
for (var propertyName in objReturn[0]) {
if (!(objReturn[0][propertyName] instanceof Function)) {
objFormInfo.arrCols.push(propertyName);
intFormColCount++;
}
}
for (var i = 0; i < objFormInfo.arrGrid.length; i++) {
strGridName = objFormInfo.arrGrid[i].gridName;
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
intColCount = 0;
for (var propertyName in objReturn[intGridStart]) {
if (!(objReturn[intGridStart][propertyName] instanceof Function)) {
intColCount++;
}
}
objFormInfo.arrGrid[i].columns = intColCount;
objFormInfo.arrGrid[i].hideList = [];
for (var propertyName in objFormInfo.objGrid[strGridName].colInfo) {
if (!(objFormInfo.objGrid[strGridName].colInfo[propertyName] instanceof Function)) {
strHideCol = objFormInfo.objGrid[strGridName].colInfo[propertyName];
if ((strHideCol.length > 5) && (strHideCol.substr(0, 5) == "hide=")) {
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
strHideCol = strHideCol.substr(5);
//for (var propertyNameCol in objReturn[intGridStart]) {
// if (!(objReturn[intGridStart][propertyNameCol] instanceof Function)) {
// strHideCol = strHideCol;
// }
//}
objFormInfo.arrGrid[i].hideList.push(strHideCol);
}
}
}
}
for (var i = 0; i < objFormInfo.arrGrid.length; i++) {
strGridName = objFormInfo.arrGrid[i].gridName;
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
intGridEnd = objFormInfo.objGrid[strGridName].gridEnd;
for (var j = 0; j < objFormInfo.arrGrid[i].hideList.length; j++) {
strHideCol = objFormInfo.arrGrid[i].hideList[j];
for (var k = intGridStart; k <= intGridEnd; k++) {
delete objReturn[k][strHideCol];
}
}
}
for (var i = 0; i < objFormInfo.arrGrid.length; i++) {
strGridName = objFormInfo.arrGrid[i].gridName;
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
intColCount = 0;
for (var propertyName in objReturn[intGridStart]) {
if (!(objReturn[intGridStart][propertyName] instanceof Function)) {
intColCount++;
}
}
objFormInfo.arrGrid[i].cleanedcolumns = intColCount;
if (intColCount > intFormColCount) {
if ((intColCount - intFormColCount) > intFormColShort) {
intFormColShort = intColCount - intFormColCount;
}
}
}
if (intFormColShort > 0) {
for (var i = 0; i < intFormColShort; i++) {
objFormInfo.arrCols.push("ExtraCol" + String(i + 1));
objReturn[0]["ExtraCol" + String(i + 1)] = "";
}
}
for (var i = objFormInfo.arrGrid.length - 1; i >= 0; i--) {
strGridName = objFormInfo.arrGrid[i].gridName;
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
intGridEnd = objFormInfo.objGrid[strGridName].gridEnd;
objReturn.splice(intGridStart, 0, {});
intColCount = 0;
for (var propertyName in objReturn[intGridStart + 1]) {
if (!(objReturn[intGridStart + 1][propertyName] instanceof Function)) {
strNewCol = propertyName.trim();
if ((strNewCol.substr(0, 1) == ">") || (strNewCol.substr(0, 1) == "^") || (strNewCol.substr(0, 1) == "<")) {
strNewCol = strNewCol.substr(1);
}
objReturn[intGridStart][objFormInfo.arrCols[intColCount]] = strNewCol;
intColCount++;
}
}
objReturn.splice(intGridStart, 0, {});
intColCount = 0;
for (var propertyName in objReturn[intGridStart + 1]) {
if (!(objReturn[intGridStart + 1][propertyName] instanceof Function)) {
switch (intColCount) {
case 0:
strNewCol = objReturn[intGridStart + 1][propertyName];
strCP = strNewCol.indexOf("/");
strNewCol = "Grid: " + strNewCol.substr(4, strCP - 4);
objReturn[intGridStart][objFormInfo.arrCols[intColCount]] = strNewCol;
objReturn[intGridStart + 1][propertyName] = objReturn[intGridStart + 1][propertyName].substr(strCP + 1);
break;
case 1:
strNewCol = "Rows: " + String((intGridEnd - intGridStart) + 1);
objReturn[intGridStart][objFormInfo.arrCols[intColCount]] = strNewCol;
break;
default:
objReturn[intGridStart][objFormInfo.arrCols[intColCount]] = "";
}
intColCount++;
}
}
for (var j = i; j < objFormInfo.arrGrid.length; j++) {
strGridName = objFormInfo.arrGrid[j].gridName;
objFormInfo.objGrid[strGridName].gridEnd = objFormInfo.objGrid[strGridName].gridEnd + 2;
if (j > i) {
objFormInfo.objGrid[strGridName].gridStart = objFormInfo.objGrid[strGridName].gridStart + 2;
}
}
strGridName = objFormInfo.arrGrid[i].gridName;
intGridStart = objFormInfo.objGrid[strGridName].gridStart;
intGridEnd = objFormInfo.objGrid[strGridName].gridEnd;
for (var j = intGridStart + 2; j <= intGridEnd; j++) {
objNewRow = new Object();
intColCount = 0;
for (var propertyName in objReturn[j]) {
if (!(objReturn[j][propertyName] instanceof Function)) {
objNewRow[objFormInfo.arrCols[intColCount]] = objReturn[j][propertyName];
intColCount++;
}
}
objReturn[j] = objNewRow;
}
}
};
Last edited by szlamany; Jan 19th, 2023 at 07:16 AM.
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
By the power invested in me, all the threads I start are Niya and Olaf free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
For example - I just wrote this code and it's got zero comments. Some of the variable are descriptive - so it's got that natural verbosity. Otherwise, I find zero ROI lately with any additional comments. If I come back to this code - I run a few examples through to re-familiarize myself, and hack and slay new code into place.
I do essentially the same. If I come back to some code, and find I have a hard time understanding a line, THEN I add a comment. After all, when I wrote it, I understood it, but the person who returned to it is a different guy. If HE has a hard time understanding it, then a comment is worthwhile. By doing this, I don't write too many comments.
On the other hand, I really started out with the Quattro Pro macro language. That language was quite deficient, but it had functions that did all the RISC operations, so it was possible to write in it as if the spreadsheet was a CPU where all the memory addresses were registers. As a logical exercise, it was really quite fascinating. From a performance perspective...it was almost unbelievably atrocious. I could see a 40x improvement in speed when I rewrote in Excel95 VBA. Still, the key point was that it was a fascinating exercise in logic...and the language had no means to add comments. No comments in what amounted to ASM...that was fun. I realized I could only work for about four hours. Beyond that, I felt like I was making progress, but I was actually creating as many bugs as I was fixing, for no net gain.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
simh is an .exe that runs under standard Windows cmd prompt. It simulates the hardware so that you can run the original software. I don't have a simh for VMS, but I do for RTSTS/E. I called the .exe pdp11.exe when I compiled the simh code with the PDP11 simulation .c/.h files. There's also RSTS/E disk images avaialble from the simh site that simh can boot from to start the OS.
Eg. This is RSTS/E running from a Windows cmd prompt on my system.
rsts.ini is:
Code:
set cpu 1m
att rl0 pdp11/rsts_full_rl.dsk
att rl1 pdp11/rsts_swap_rl.dsk
b rl0
where .dsk are the disk image files.
For startup:
Code:
c:\MyProgs\pdp>pdp11 rsts.ini
PDP-11 simulator V4.0-0 Beta git commit id: 247bd8d5
Disabling RK
Disabling HK
Disabling TM
Device DP23: does not interrupt - device disabled.
Device DP26: does not interrupt - device disabled.
Device DP27: does not interrupt - device disabled.
Device DP30: does not interrupt - device disabled.
RSTS V7.0-07 llama (DL0)
Option:
LF then does the normal RSTS/E startup - with pages of startup messages. Once completed, then you can login as 1,2 with password of SYSTEM
Ready
LIST
TEST 01:29 PM 19-Jan-98
10 LET A = 10
20 LET B = 20
30 LET C = 30
40 PRINT A,B,C
Ready
COMPILE
Ready
RUN
TEST 01:30 PM 19-Jan-98
10 20 30
Ready
Note that you can't set of date of 2023 - as only 2 digit year can be entered, and 23 isn't allowed!
Last edited by 2kaud; Jan 19th, 2023 at 08:48 AM.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
I also remember punched cards - but for Cobol. We had time-shared Fortran using teletypes/vdu monitors. Using batch Cobol was one of the worst experiences with computing I've ever had... In their day line-editors were fine if you had a good one. I used them for over 20 years on various systems - and even wrote a couple of simple but powerful ones where the existing ones lacked functionality. You had a printout of the code, you'd mark the required changes, then you'd edit the changes. Easy-peasy no problem...
Last edited by 2kaud; Jan 20th, 2023 at 04:46 AM.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
Only punchcard programmed machine I operated was a Raytheon mainframe used to process seismic data analysis runs.
I was an operator on a Vax 11/780, the only such Vax in South Africa, given special dispensation by the President of the USA on the proviso that no S.A. government personnel were allowed anywhere near it. Apartheid era computing.
My first Vax was an 11/750, then a brand new MicroVax. The main console was a teleprinter. The 11/750 booted from a TU58 tape for standalone backups. I was a BASIC boy before then but soon learned to script/code in DCL, gosub subroutines were a thing and there was no alternative. It was Vax/Alpha all the way but I still retained some BASIC involvement (GWBasic,QB &c).
Still retain a huge fondness for DEC and its products. Those 64bit Alphas and their capabilities were so ahead of their time in hardware and o/s. I still dip into that world from time to time.
By the power invested in me, all the threads I start are Niya and Olaf free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
Well Dave Cutler, who was the mastermind behind VMS and PRISM (which became Alpha) was the architect of Microsoft Windows NT os (the MS os from which Windows 11 is derived). He still works at Microsoft, supposedly on Hyper-V host os. One of the greats.
I used several DEC VAX-11's during the 1980's and loved them. It's competitor then was DG Eclipse/Eagle. But IMO VAX was far superior. No wonder DG lost many customers to DEC! Moving DG Business Basic programs to DEC was quite lucrative.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
My VAX clients were previously my PDP clients and bunch of them hung around while I moved to a VB6 version of my apps and to what is now a web version running .NET in IIS in the back end.
People today see PowerShell as a great tool - DOS .bat files on steroids. DCL had all that and more.
Just thinking about the TPU editor - defining macros to do powerful single stroke large scale edits.
Back in those days I had 5 programmers working under me and a librarian to keep code backups and what not. Magtape backup room was insane...
I still have write-rings of many odd colors!
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
I moved from DEC systems to Pick systems. IMO it was the best for data management systems. It had Basic, Proc (advanced .bat), Access (for producing reports), Text Processing, Spreadsheet and Assembler (most unusual - nothing else like it!). It was also available on various hardware platforms (including IBM) so you weren't tied to one manufacturer.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
We specialize in developing web and mobile applications, enterprise solutions, e-commerce systems, and other custom software products. Our team is committed to delivering high quality, innovative solutions that meet our clients’ expectations. We understand the importance of meeting tight deadlines and make sure that all projects are delivered in a timely manner https://mlsdev.com.
Last edited by kimimiles; Jan 26th, 2023 at 04:40 PM.