flat assembler
Message board for the users of flat assembler.

flat assembler > Examples and Tutorials > Custom Source Code Viewer

Author
Thread Post new topic Reply to topic
uart777



Joined: 17 Jan 2012
Posts: 369
Preview:
Image
Image
Download: http://sungod777.zxq.net/codeview.zip

How-To: Scroll: Mouse, wheel, UP/DOWN keys. Next theme: Right click. Select File: LEFT/RIGHT keys
Post 07 Feb 2013, 04:35
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4203
Location: 2018
coool

but at least, under windows, it would be better to render in a window.

the over use of gradient is a bit too much also. Smile

the scroll bars are "bugged" in a sense that if you hold the clic button and goes out the scroll bar, you should continue to interact with the cursor.
Post 07 Feb 2013, 10:34
View user's profile Send private message Visit poster's website Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1181
Location: Unknown
Stupid post removed.


Last edited by HaHaAnonymous on 28 Feb 2015, 21:41; edited 1 time in total
Post 07 Feb 2013, 12:23
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1391
Location: Toronto, Canada
When every little item on screen is gradiented -- it does not look good.
Or maybe it is just me?
Post 07 Feb 2013, 17:31
View user's profile Send private message Send e-mail Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1181
Location: Unknown
Stupid post removed.


Last edited by HaHaAnonymous on 28 Feb 2015, 21:39; edited 2 times in total
Post 07 Feb 2013, 17:45
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
Again, my examples are intended for LL systems/graphics programmers who must write their own everything from scratch.

This example demonstrates how to draw custom text/code manually using my raster FONT.INC engine and no OS-specific code (TextOutA). 100% customizable: Themes, color, fonts, sizes, clarity, etc. You can easily change the entire interface just by editing 1-3 lines and/or by replacing the default font file. Included themes are extreme hypothetical graphics examples and not meant to be used literally.

I offer general ideas, algorithms, sketches and templates, not specific implementations. If I submitted a joystick configuration utility for example, would you complain that it's not a complete game?

Scrollbar was a quick sketch until I finish the custom control. Toolbar was left blank for icons: next, previous, home, search, etc. It will evolve into like a .PDF viewer, book reader or mini web browser. Future versions will feature clear fonts, dynamic zoom and velocity-based scrolling depending on mouse wheel strength.

Thanks for viewing.
Post 07 Feb 2013, 23:25
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6020
Location: Poland
uart777

Your code viewer is impressive from the graphical point of view but I'd like to tell something related rather to its internal structure. Now it's not so much important but when you migrate to real source code editor it may be crucial in some situations. I think you should improve the parsing mechanism because, as I suppose, now the decimal numbers are treated as integral tokens even if they in fact are components of bigger strings such as hex numbers and identifiers, see these screenshots:

Image

Image

Moreover, the assembler keywords shouldn't be distinguished if they are parts of the identifiers:

Image

or, like in the example presented below, parts of the instruction names:

Image

I guess that the parsing mechanism may be changed this way that it would search the longest matches first instead of current "ungreedy" matching, so it would search the tokens in the order presented below:
  1. comments

  2. identifiers

  3. assembler keywords

  4. hex numbers

  5. signed decimal numbers

  6. unsigned decimal numbers
. Smile
Post 19 Feb 2013, 17:32
View user's profile Send private message Visit poster's website Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
MHajduk: Updated SYNTAX.INC:

Code:
; $$$$$$$$$$$$$$$ Z77 ASM LIBRARY $$$$$$$$$$$$$$$$
; *************** SUNGOD SOFTWARE ****************
; ????????????????? SYNTAX.INC ???????????????????

; SOURCE CODE WITH SYNTAX HIGHLIGHTING

; font code1-5 is compatible with all resolutions

; code1 QVGA-VGA
; code2 SVGA-XGA
; code3 >=XGA
; code4/5 HD+

align 4

BOOLEAN in.comment?=NO, in.number?=NO,\
 in.text?=NO, in.name?=NO, in.keyword?=NO

macro reset.in.source 
let in.comment?=NO,\
 in.number?=NO, in.text?=NO,\
 in.name?=NO, in.keyword?=NO


COLOR page.color, code.color, keyword.color,\
 number.color, symbol.color, text.color,\
 comment.color, shade.color

macro set.syntax.colors \
 pc, cc, kc, nc, sc, tc, coc 
let page.color=pc, code.color=cc,\
 keyword.color=kc, number.color=nc,\
 symbol.color=sc, text.color=tc,\
 comment.color=coc
get shade.color=lightness page.color, -192


macro set.default.syntax.colors 
set.syntax.colors 0FFFFFFh, BLACK, 04040FFh,\
0EF1070h, 08000AFh, 0FF1777h, 0777777h


;;;;;;;;;;;;;;;;;; SOURCE THEME ;;;;;;;;;;;;;;;;;;

MESSAGEZ source.themes, source.theme, ST,\
 DEFAULT='Professional',\
 BLUE_CONSOLE='Sexy Blue Console',\
 BLACK_CONSOLE='Classic Black Console',\
 PURPLE_HAZE='Purple Haze',\
 ALIEN_TERMINAL='Alien Terminal'

TEXT source.theme.f='Theme %t'
macro set.source.theme theme
  let source.theme=theme 

macro next.source.theme 
.if source.theme<ST_LAST-1
  let source.theme++
.else
  let source.theme=0
.end
update.source.colors
let display.theme?=1


macro previous.source.theme 
.if source.theme>0
  let source.theme--
.else
  let source.theme=ST_LAST-1
.end
update.source.colors
let display.theme?=1


; pc, cc, kc, nc, sc, tc, coc

function update.source.colors
.if source.theme=0 ; ST_DEFAULT
  jmp .default.colors
.else.if source.theme=ST_BLUE_CONSOLE
  set.syntax.colors 40h, WHITE, 000BAFFh,\
  0FFFF77h, 20FF20h, 0B700C7h, 02200FFh
.else.if source.theme=ST_BLACK_CONSOLE
  set.syntax.colors BLACK, WHITE, 04057FFh,\
  0B700C7h, 20FF20h, 0FF27A7h, 777777h
  let shade.color=GRAY25
.else.if source.theme=ST_PURPLE_HAZE
  set.syntax.colors 11032Dh, LILAC, 20FF20h,\
  0B700C7h, 04057FFh, 0FF27A7h, VIOLET
  let shade.color=DARK.VIOLET ;PURPLE
.else.if source.theme=ST_ALIEN_TERMINAL
  set.syntax.colors BLACK, 10FF10h, WHITE,\
  0D4FF1Fh, 0F9FF0Dh, POWER.BLUE, 137600h
  let shade.color=72FF13h
.else
  .default.colors
  set.default.syntax.colors
.end
endf

;;;;;;;;;;;;;;;;; ASM SOURCE CODE ;;;;;;;;;;;;;;;;

; words to highlight in ASM source

TEXTS asm.keywords=\
'!if', '.else', '.else.if', '.end', '.endl',\
'.endw', '.for', '.if', '.loop', '.while',\
'align', 'allocate', 'allocate.p', 'allocate.x',\
'byte', 'close', 'code', 'common', 'create',\
'destiny', 'db', 'dd', 'define', 'destroy', 'dword',\
'draw', 'else', 'end', 'endf', 'equ', 'escape',\
'escape?', 'exit', 'fail', 'fail?', 'false', 'fix',\
'forward', 'function', 'get', 'if', 'include',\
'integer', 'key', 'let', 'local', 'locale', 'locals',\
'macro', 'main', 'match', 'mouse', 'not', 'numeric',\
'omega', 'open', 'origin', 'powers', 'read',\
'render', 'ret', 'return', 'reverse', 'seek',\
'source', 'string', 'token', 'timer', 'true',\
'try', 'use', 'vga', 'virtual', 'word', 'write',\
'ARRAY', 'ASSUME', 'BOOLEAN', 'BOX', 'BYTE',\
'COLOR', 'ENDS', 'FONT', 'IMAGE', 'INFINITE',\
'INHERIT', 'INVALID', 'NO', 'NOTHING', 'NUMBER',\
'TEXT', 'STRUCTURE', 'TYPE', 'VOID', 'WORD', 'YES'

; search alphabetic text array...

function text.array.equal.az, ta, t, n
locals i
let eax=t
.loop i=0 to n
  let eax=i, eax<<2, eax+ta
  text.compare t, eax
  .if not eax
    return i
  .end
.endl
@@
let eax=INVALID
endf

macro .if.asm.keyword 
text.array.equal.az asm.keywords,\
 token, asm.keywords.$
.if eax not INVALID


; a colorful variation of draw.text FONT
; that draws Z77 ASM source code...

function draw.asm, t, x, y
locals i, p, c, cx, cy, fc, ix, iy
let eax=&ix, ecx=&iy
text.insets eax, ecx
let eax=ix, x+eax, ecx=iy, y+ecx,\
 eax=t, p=eax, i=0, cy=y

.while byte eax      ; draw all characters
  let ecx=i,\        ; x=i*font.w+x
  ecx*font.w,\
  ecx+x, cx=ecx,\
  eax=p,\            ; get c
  eax=>eax, c=eax

  .if eax=0Dh          ; return?
    let p++,\        ; skip
    i=0,\            ; reset x
    ecx=font.h,\
    cy+ecx,\         ; y+font.h
    in.comment?=NO,\
    in.name?=NO,\
    in.keyword?=NO,\
    ecx=screen.h
    .if cy>ecx
      escape
    .end
    jmp .next
  .end

  .if in.comment?
    let fc=comment.color
    jmp @f
  .end
  .if in.text?
    .if c not ''''
      let fc=text.color
      jmp @f
    .end
  .end
  set.source p
  get.token

  .if.is c, NUMBER
    ; if previous was identifier, skip
    let eax=p, ecx=>eax-1
    .if.c NAME
      jmp @f
    .end
    let fc=number.color
    jmp @f
  .end

  .if.is c, SYMBOL
    .if c=';' ; comment?
      let fc=comment.color,\
      in.comment?=YES
      jmp @f
    .end

    .if c='''' ; text?
      let fc=text.color
      toggle in.text?
      jmp @f

    .else
      let fc=symbol.color,\
       in.keyword?=NO
      jmp @f
    .end
  .end

  ; if previous character is identifier,
  ; skip keyword check...

  .if i
    .if not in.keyword?
      let eax=p, ecx=>eax-1
      .if.c NAME
        jmp @f
      .end
    .end
  .end

  .if.asm.keyword ; keyword?
    let fc=keyword.color,\
    in.keyword?=YES
    jmp @f
  .end
  .if in.keyword?
    .if.is c, END
      let in.keyword?=NO
    .else
      let fc=keyword.color
      jmp @f
    .end
  .end

  let fc=code.color  ; default
  @@
  set.font.color fc
  draw.c c, cx, cy ; draw character
  let i++
  .next
  let p++, eax=p ; eax=p for while
.endw
endf

function draw.code, t, x, y
.if parse.type&PT_ASM or PT_Z77
  draw.asm t, x, y
.else.if parse.type&PT_C or PT_CPP
  ; draw.cpp t, x, y
.else.if parse.type&PT_HTML
  ; draw.html t, x, y
.else.if parse.type&PT_BASIC
  ; draw.basic t, x, y
.end
endf

; 2-DO CUSTOM HELP VIEWER FOR Z77 ASM/INC
; FILES. FORMAT

; <t>         ; enable text, disable code
; <c>         ; enable code, disable text
; <f='name'>  ; set font style
; <f>         ; restore previous font
; <#000000h>  ; set font color
; <#>         ; restore previous color
; <a=LEFT>    ; set alignment
; <a>         ; restore previous alignment
; <i='name'>  ; insert image
; <b='name'>  ; insert button
; <link='to'> ; start link
; <l>         ; end link
; <s>         ; space
; <r>         ; return
; << >>       ; < >    


PARSE.INC:
Code:
; $$$$$$$$$$$$$$$ Z77 ASM LIBRARY $$$$$$$$$$$$$$$$
; *************** SUNGOD SOFTWARE ****************
; ?????????????????? PARSE.INC ???????????????????

; load.source $file
; set.source $s     ; set source address
; end.source        ; deallocate

; "skip" advances source while or until type.
; "copy" copies source to token then increments
; while type. copy.until.c copies until the
; specified character and while not 0. to copy
; until type, invert the character BITs
; "while not return" = "until return"

; skip.while type
; skip.until type
; copy.while type
; copy.until.c c

; skip.space   ; skip only spaces and tabs
; skip.comment
; skip.x       ; skip all whitespace, returns
               ; and comments

; copy token from source. return 0 if end
; or unrecognized

; copy.token   ; no skip
; read.token   ; skip *only spaces and tabs
; get.token    ; skip all whites/comments first

; * read.token will only skip returns and
; comments if previous line ends with ,=
; which are continuation symbols

; parse.symbol ; no skip...
; parse.c
; parse.name
; parse.number
; parse.text

align 8

VOID source.type, source.filename,\
source.base, source.last, source.base.last

VOID token
NUMBER token.type, token.class,\
 token.size, token.value, token.index
VOID token.address

NUMBER line.number=1,\
 number.lines

powers PT_ASM, PT_Z77, PT_EZ7, PT_C, PT_CPP,\
 PT_BASIC, PT_HTML, PT_IDENTIFY

NUMBER parse.type=PT_ASM+PT_IDENTIFY

;;;;;;;;;;;;;;;;; SYNTAX ERRORS ;;;;;;;;;;;;;;;;;;

ARRAY syntax.errors2*KB
NUMBER se.limit=3

VOID error.t
TEXT error.m='Error #$line %t',\
format.t32
error.t equ ?t

MESSAGES se.keys,\
SE_KEY_FILE='$file', SE_KEY_LINE='$line',\
SE_KEY_WHY='$why', SE_KEY_TOKEN='$t'

; report error, add message to
; syntax.errors array

function _syntax.error, i
locals p, e
let ecx=se.limit ; maximum?
.if syntax.errors.n>=ecx
  return 0
.end
try p=array.expand syntax.errors
text.copy error.t, error.m
let ecx=i
print p, error.t, se.errors+ecx*4
let eax=p
endf

macro syntax.error e  _syntax.error SE_##e 

if used !_syntax.error
MESSAGES se.errors,\
SE_0       ='None',\
SE_SYNTAX  ='Syntax',\
SE_LOAD    ='Load $file',\
SE_UNEXPECT='$t Unexpected',\
SE_EXPECTN ='$t Number expected',\
SE_EXPECTA ='$t Name expected',\
SE_NAME    ='$t Invalid name',\
SE_RESERVE ='$t Reserved name',\
SE_UNDEFINE='$t Undefined',\
SE_REDEFINE='$t Redefinition',\
SE_SIZE    ='Invalid size',\
SE_EXPECTT ='$t Text expected',\
SE_ENDB    ='No end for $t',\
SE_ENDT    ='Text has no end ''',\
SE_PARENTH ='Unmatched parenthesis',\
SE_PARAMS  ='$t Invalid # parameter/s',\
SE_PTYPE   ='$t Invalid parameter type',\
SE_ASSIGN  ='$t Invalid assignment',\
SE_POINTER ='$t Invalid pointer syntax'
end if

;;;;;;;;;;;;;;;;;;; KEYWORDS ;;;;;;;;;;;;;;;;;;;;;

; is keyword? return index or INVALID. for case
; sensitive search set.case 0 before then
; restore it after

function is.keyword, name
locals i
.loop i=0 to keywords.$
  let ecx=i
  .if.text.equal name, keywords+ecx*4
    return i
  .end
.endl
let eax=INVALID
endf

macro .if.keyword name 
is.keyword name
.if eax not INVALID


if used !is.keyword
MESSAGES keywords,\
K_CELSE='#else', K_CEND='#end', K_CIF='#if',\
K_ALIAS='alias', K_ALIGN='align',\
K_ARRAY='array', K_ASSUME='assume',\
K_BIT='bit', K_BOOLEAN='boolean',\
K_BYTE='byte', K_CODE='code', K_COLOR='color',\
K_DATA='data', K_DEFINE='define',\
K_DEFINED='defined', K_DRAW='draw',\
K_ELSE='else', K_EMIT='emit', K_END='end',\
K_FONT='font', K_FUNCTION='function', K_IF='if',\
K_IMAGE='image', K_IMPORT='import',\
K_INCLUDE='include', K_INJECT='inject',\
K_INHERIT='inherit', K_INTEGER='integer',\
K_LOOP='loop', K_MACRO='macro',\
K_MODERM='mode.rm', K_NUMBER='number',\
K_NUMERAL='numeral', K_NUMERIC='numeric',\
K_NUMERO='numero', K_POWERS='powers',\
K_REAL='real', K_REAL8='real8', K_RETURN='return',\
K_SIB='sib', K_SYNTAX='syntax', K_TEXT='text',\
K_TYPE='type', K_UNDEFINE='undefine',\
K_UNION='union', K_UNTIL='until', K_USE='use',\
K_USED='used', K_VARIANT='variant',\
K_VOID='void', K_WHILE='while'
end if

;;;;;;;;;;;;;;;;; SET/LOAD SOURCE ;;;;;;;;;;;;;;;;

function set.source, s
.if s=INVALID
  return source
.end
let eax=s, source.last=source,\
 source.base.last=source.base,\
 source=eax, source.base=eax,\
 line.number=1
endf

function reset.source
let source=source.last,\
source.base=source.base.last
endf

function load.source, file
try load.text file
set.source eax
let source.filename=file
endf

function end.source
destroy source.base
destroy token
endf

;;;;;;;;;;;;;;;;;; SKIP, COPY ;;;;;;;;;;;;;;;;;;;;

; advance source while type. return end
; address or 0

function skip.while, type
let eax=source
@@
 let ecx=>eax, ecx=>TT+ecx
 test ecx, type
 jz @f
 let eax++
jmp @b
@@
let source=eax
.if byte eax=0
  let eax=0
.end
endf

; advance source until type or 0

function skip.until, type
let eax=type, not eax
skip.while eax
endf

; copy token=source while type

function copy.while, type
let eax=source, edx=token
@@
 let ecx=>eax, ecx=>TT+ecx
 test ecx, type
 jz @f
 let cl=eax, edx=cl, eax++, edx++
jmp @b
@@
let source=eax, byte edx=0
.if byte eax=0
  let eax=0
.end
endf

; copy token=source until character and
; while not 0

function copy.until.c, c
let eax=source, edx=token
@@
 let ecx=>eax
 test ecx, ecx
 jz @f
 cmp ecx, c
 je @f
 let cl=eax, edx=cl, eax++, edx++
jmp @b
@@
let source=eax, byte edx=0
.if byte eax=0
  let eax=0
.end
endf

;;;;;;; SKIP WHITESPACE, RETURNS, COMMENTS ;;;;;;;

macro skip.space    skip.while C_SPACE 
macro skip.white    skip.while C_WHITE 
macro skip.comment  skip.until C_RETURN 

function skip.x
.skip
let eax=source
.if byte eax=0   ; EOF
  let eax=0
  escape
.end
let ecx=>eax
.if.c SPACE        ; SPACE
  try skip.space
.end
let eax=source
.if byte eax=';' ; COMMENT
  try skip.comment
  jmp .skip
.end
let eax=source
.if byte eax=0Dh ; RETURN?
  let source+2,\
  line.number++
  jmp .skip
.end
let eax=1
endf

;;;;;;;;;;;;; TOKEN TYPE/VALUE/SIZE ;;;;;;;;;;;;;;

macro set.token.type t   let token.type=C_#t 
macro set.token.class t  let token.class=t 
macro set.token.value v  let token.value=v 

function get.token.size
cmp token.value, 255
jg .32
cmp token.value, -128
jl .32
let token.size=8
jmp .8
.32 let token.size=32
.8
endf

macro .if.token.is t
 .if token.type=C_#t 
macro .if.token.is.not t
 .if token.type not C_#t 
macro .else.if.token.is t
 .else.if token.type=C_#t 

;;;;;;;;;;;; COPY NAME/NUMBER/TEXT/ETC ;;;;;;;;;;;

function parse.symbol
set.token.type SYMBOL
let eax=source, edx=token,\
 cl=eax, edx=cl, eax++, edx++,\
 ecx&0FFh, token.value=ecx,\
 source=eax, byte edx=0,\
eax=C_SYMBOL
endf

function parse.text
let eax=source, eax++,\ ; past '
 edx=token
.while byte eax
  let ecx=>eax
  .if ecx=27h             ; '
    .if byte eax+1=27h  ; 2 '' for I''m
      let ecx=27h         ; can''t, etc
    .else
      jmp @f
    .end
  .end
  .get
  let edx=cl, eax++, edx++
.endw
.if byte eax=0     ; end not found
  let source=eax,\
  byte edx=0
  syntax.error ENDT  ; 'Text has no end'
  return 0
.end
@@
.if ecx=27h
  let eax++
.end
set.token.type TEXT
let source=eax, byte edx=0,\
eax=C_TEXT
endf

function parse.number
locals n, c, b, s
copy.while C_DIGIT
let eax=source,\
 ecx=>eax-1,\        ; get last character
 c=ecx, b=BASE,\ ; save current base
 BASE='n'            ; default signed decimal
.if.c NUMBER           ; ends with 0-9?
  jmp .convert
.end
cmp ecx, 'h'           ; hexadecimal
je .base
cmp ecx, 'b'           ; binary
je .base
cmp ecx, 'k'           ; kilobyte
je .x
cmp ecx, 'm'           ; megabyte
je .x
jmp .error             ; unrecognized
.base
let BASE=ecx         ; reset base
.x                    ; remove suffix
let byte edx-1=0
.convert              ; convert to number
get n=t2n token
let BASE=b         ; restore previous base
.if c='k'
  shl n, 10          ; k=n*1024
.else.if c='m'
  shl n, 20          ; m=n*1048576
.end
set.token.type NUMBER
set.token.value n
get.token.size
let eax=C_NUMBER
escape
.error let eax=0
endf

function parse.name
try copy.while C_NAME
.if parse.type&PT_IDENTIFY
  call !identify.name
.end
let eax=token.type
endf

; copy.token - copy next token from source.
; numbers must begin with 0-9 and may contain
; A-F/a-f and end with h/b/k/m/H/B/K/M.
; names/identifiers may consist of A-Z, 0-9
; or _.?!@$ but cannot begin with a number.
; examples

; numbers 7Fh, 0AAh, 1010b, 64k 65536
; names ?image.p, @color, $file, clear_screen?

; hex numbers that begin with letters must be
; prefixed with 0 0FFh

; '-' is recognized as a generic symbol. it can
; have different meanings -aINVALID-c--.
; the expression parser distinguishes between
; unary, negative, subtract or decrement
; depending on the context

function copy.token
set.token.type 0
set.token.class 0
set.token.value 0
let eax=source
.if byte eax=0
  jmp .r0
.end
let ecx=>eax
.if.c NUMBER
  parse.number
  return
.end
.if.c SYMBOL
  .if ecx=27h  ; '
    parse.text
    return
  .end
  parse.symbol
  return
.end
.if.c NAME
  parse.name
  return
.end
.r0 let eax=0
endf

; skip spaces and tabs then copy token.
; this will only skip return\s and comments
; if previous line ends with ,= which are
; continuation symbols

function read.token
cmp token, ','
je .skip.x
cmp token, '='
jne .skip.s
.skip.x try skip.x
jmp .copy
.skip.s try skip.space
.copy copy.token
endf

; skip all whitespace, returns and comments
; then copy token

function get.token
try skip.x
copy.token
endf

macro .if.token.equal t
 !if text.equal, token, t 
macro .if.token.not t
 !if.not text.equal, token, t 
macro .else.if.token.equal t
 !else.if text.equal, token, t 

macro .if.next.symbol s 
skip.space
.if byte eax=s


macro .if.next.symbol.not s 
skip.space
.if byte eax not s


; get and expect type

function get.x, t
try skip.space
try copy.token
let ecx=token, ecx=>ecx
.if.n ecx&t
  .if not token.class
    .if.c SYMBOL
      syntax.error SYNTAX
    .else
      syntax.error UNDEFINE
    .end
  .end
.end
let eax=source
endf

macro get.name    get.x C_ALPHA 
macro get.number  get.x C_NUMBER 
macro get.value   get.x C_ALNUM 
macro get.text    get.x C_TEXT 

;;;;;;;;;;;;;;;;;; DEFINITIONS ;;;;;;;;;;;;;;;;;;;

; define name value

STRUCTURE DEFINITION
 NUMBER type         ; 'l'/abel, 'm'/acro, etc
 TEXT name32
 VOID value          ; or address/index
ENDS ?define

align 8
ARRAY definesDEFINITION.$

; is name defined? return index or INVALID

function is.define, name
locals i
.loop i=0 to defines.n
  array.index defines, i
  let eax=&?define.name+eax
  .if.text.equal name, eax
    return i
  .end
.endl
let eax=INVALID
endf

macro .if.define name 
is.define name
.if eax not INVALID


; is name defined of type? return index or INVALID

function is.define.type, type, name
locals i
get i=is.define name
.if i not INVALID
  array.index defines, eax
  let ecx=?define.type+eax
  .if ecx=type
    return i
  .end
.end
endf

macro .if.define.type type, name 
is.define.type type, name
.if eax not INVALID


; validate name. return 0 if invalid

function valid.name, name
.if.keyword name        ; reserved keyword?
  syntax.error RESERVE
  return 0
.end
.if.define name         ; redefinition?
  syntax.error REDEFINE
  return 0
.end
text.n name
.if eax>23                ; name too long?
  syntax.error NAME
  return 0
.end
let eax=1
endf

; create new define

function create.define, type, name, value
try valid.name name
try array.expand defines
let ?define.type+eax=type,\
?define.value+eax=value
push eax
let eax+?define.name
text.copy eax, name
pop eax
endf

; remove define

function un.define, name
.if.defined name
  array.remove defines, eax
.end
endf

; get define.name by index. note "i/name"
; must be valid for these...

function get.define.name, i
array.index defines, i
.if eax not INVALID
  let eax+?define.name
.end
endf

; get define.value by index

function get.define.value, i
array.index defines, i
.if eax not INVALID
  let eax=?define.value+eax
.end
endf

; get define.value by name

function get.define, name
.if.define name
  get.define.value eax
.end
endf

; assign define.value by name

function set.define, name, v
.if.define name
  let ?define.value+eax=v
.end
endf

; display defines for testing

function show.defines
locals i
jmp @f
TEXT define.f='Type %c. Name %t. Value %hh'
@@
.loop i=0 to defines.n
  array.index defines, i
  let ecx=&?define.name+eax,\
   edx=?define.value+eax,\
   eax=?define.type+eax
  print ?t, define.f, eax, ecx, edx
  log ?t
.endl
execute log.file
endf

; identify name token

BOOLEAN identified?

function identify.name
let identified?=YES
.if.keyword token       ; keyword?
  set.token.value eax
  set.token.type KEYWORD
  return 1
.end
.if.define token        ; define?
  get.define.value eax
  set.token.value eax
  set.token.type NUMBER
  set.token.class 'd'
  return 1
.end
set.token.type NAME
let identified?=NO,\    ; undefined
eax=1
endf

;;;;;;;;;;;;;;;;;;;; DEFINE ;;;;;;;;;;;;;;;;;;;;;;

; process define statement. example
; define SIZE 4k ; comment

function parse.define
try get.name
text.copy ?t, token
try read.token
create.define 'd', ?t, token.value
endf

;;;;;;;;;;;;;;;;;;;;; LABELS ;;;;;;;;;;;;;;;;;;;;;

; create new label at ip

function create.label, name
create.define 'l', name, omega
endf

macro is.label name  is.define.type 'l', name 

function offset?, name
is.label name
.if eax not INVALID
  get.define name
.end
endf

macro rva? a 
offset? a
let eax+1000h, eax-200h


function address?, a
rva? a
.if eax not INVALID
  let eax+400000h
.end
endf    


Last edited by uart777 on 07 Aug 2013, 19:04; edited 1 time in total
Post 21 Feb 2013, 23:39
View user's profile Send private message Reply with quote
KevinN



Joined: 09 Oct 2012
Posts: 161
Thanks uart
Post 22 Feb 2013, 04:30
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6020
Location: Poland
uart777 wrote:
MHajduk: I have corrected this in my latest version of the program. It was an easy fix. It should not highlight partial keywords like password.
Yeah, seems that everything is OK now. Smile I was only wondering whether the unary minus sign should be colored with the same color as decimal number it precedes or not. I don't know if it would be a problem to distinguish the unary plus and minus from the corresponding binary operators. Anyway, it's not so important IMHO.
uart777 wrote:
Sorry to change the subject but for some reason, you remind me of David Attenborough who is a genius in my mind. I love his connection with nature/animals and I watch all of his BBC documentaries. What a great man! Smile
Well, I feel truly honored by such a comparison, thank you. I've never thought about myself this way, I'm rather concerned on admiring others' talents and, talking honestly, I'm really thankful to all those creative people such as artists, scientists and masters of their profession because their creations somehow hold me on this world, give sense to my life. Smile
Post 22 Feb 2013, 13:12
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.