2022-05-15 22:32:35 +02:00
import * as fs from "fs" ;
var path = process . argv [ 2 ] ;
var pathout = process . argv [ 3 ] ;
if ( ! path || ! pathout ) {
console . log ( "PLease this Schema: node ToAs.js [path] [pathout]" ) ;
process . exit ( ) ;
}
var file = fs . readFileSync ( path ) . toString ( ) ;
function error ( msg , l = null , c = null ) {
var out = "Error"
if ( l != null && c != null ) out += ` in line ${ l } and character ${ c } ` ;
out += ": " + msg ;
console . log ( "\x1b[31m" , out , "\x1b[0m" ) ;
process . exit ( 1 ) ;
}
2022-06-16 14:02:01 +02:00
var lispSeperator = [ " " , ":" , "\n" ] ;
2022-05-15 22:32:35 +02:00
function cutCmd ( code , line , chars ) {
if ( ! code . startsWith ( "(" ) ) return [ "" , error ( "Compiler Error" , line , chars ) ] ;
if ( ! code . endsWith ( ")" ) ) return [ "" , error ( "Compiler Error" , line , chars ) ] ;
code = code . substring ( 1 , code . length - 1 ) ;
var countLinesBegin = line ;
var countCharsBegin = chars ;
var countLines = line ;
var countChars = chars ;
var inC = 0 ;
var wasinC = false ;
var inStr = 0 ;
var buffer = "" ;
var i = 0 ;
var out = [ ] ;
function finishBuff ( ) {
out . push (
wasinC ?
new LISPcmd ( buffer . trim ( ) , countLinesBegin , countCharsBegin )
:
new LISPstring ( buffer . trim ( ) , countLinesBegin , countCharsBegin )
) ;
countLinesBegin = countLines ;
countCharsBegin = countChars ;
buffer = "" ;
wasinC = false ;
}
for ( var i = 0 ; i < code . length ; i ++ ) {
countChars ++ ;
//console.log(code,countLines,countChars);
let c = code [ i ] ;
if ( ! inC && ! inStr ) {
countLinesBegin = countLines ;
countCharsBegin = countChars ;
}
if ( c == "\\" ) {
buffer += code [ ++ i ] ;
continue ;
}
if ( inStr ) {
if ( c == "\n" ) {
countLines ++ ;
countChars = 0 ;
} else if ( c == '"' ) {
if ( ! inC ) finishBuff ( ) ;
inStr = false ;
} else {
buffer += c ;
}
continue ;
}
if ( c == '"' ) {
inStr = true ;
continue ;
}
if ( c == ";" && ! inC ) {
while ( code [ ++ i ] != "\n" ) { }
countLines ++ ;
countChars = 0 ;
continue ;
}
if ( c == "\n" ) {
countLines ++ ;
countChars = 0 ;
}
2022-06-16 14:02:01 +02:00
if ( /*(c == " "||c=="\n")*/ lispSeperator . includes ( c ) && ! inC ) {
2022-05-15 22:32:35 +02:00
if ( buffer . trim ( ) != "" ) {
finishBuff ( ) ;
}
continue ;
}
if ( c == "(" ) {
if ( ! inC && buffer . trim ( ) != "" ) {
finishBuff ( ) ;
}
inC ++ ;
wasinC = true ;
}
if ( c == ")" ) {
inC -- ;
if ( inC < 0 ) error ( "Closing braket to much!" , countLines , countChars ) ;
if ( ! inC ) {
buffer += c ;
finishBuff ( ) ;
continue ;
}
}
buffer += c ;
}
if ( inStr ) error ( "Missing closing quotation mark!" , countLines , countChars ) ;
if ( inC ) error ( "Missing closing braket!" , countLines , countChars ) ;
if ( buffer . trim ( ) != "" ) finishBuff ( ) ;
return out ;
}
class LISPstring extends String {
# l ;
# c ;
constructor ( string , line , char ) {
super ( string ) ;
this . # l = line ;
this . # c = char ;
}
get lineCount ( ) {
return this . # l ;
}
get charCount ( ) {
return this . # l ;
}
get pos ( ) {
return [ this . # l , this . # c ] ;
}
}
class LISPcmd extends Array {
# l ;
# c ;
constructor ( code , line , char ) {
var childs = cutCmd ( code , line , char ) ;
super ( ... childs ) ;
this . # l = line ;
this . # c = char ;
}
get lineCount ( ) {
return this . # l ;
}
get charCount ( ) {
return this . # l ;
}
get pos ( ) {
return [ this . # l , this . # c ] ;
}
}
var data = new LISPcmd ( "(\n" + file + "\n)" , 0 , 0 ) ;
//console.log(JSON.stringify(data));
function getType ( data ) {
/ * i f ( d a t a = = " e m p t y " ) {
return [ "emp" , "" ] ;
} * /
if ( data == "true" ) {
return [ "bool" , 1 ] ;
}
if ( data == "false" ) {
return [ "bool" , 0 ] ;
}
if ( data == "NaN" ) {
return [ "num" , NaN ] ;
}
/ * i f ( t y p e o f d a t a = = " s t r i n g " & & d a t a . s t a r t s W i t h ( ' " ' ) & & d a t a . e n d s W i t h ( ' " ' ) ) {
return [ "str" , data . slice ( 1 , - 1 ) ] ;
} * /
if ( ( data instanceof LISPstring ) && ! isNaN ( data ) /*!data.match(new RegExp("[^0-9.-e+]","g"))*/ ) {
return [ "num" , Number ( data ) ] ;
}
if ( data instanceof LISPcmd /*Array.isArray(data)*/ ) {
return [ "code" , data ] ;
}
return [ "var" , data ] ;
}
var nid = 0 ;
var dataTypes = {
2022-06-16 14:02:01 +02:00
uint32 : { ptype : 0 , size : 4 , mask : null } ,
uint16 : { ptype : 0 , size : 2 , mask : 0xffff } ,
uint8 : { ptype : 0 , size : 1 , mask : 0xff } ,
int32 : { ptype : 1 , size : 4 , mask : null } ,
int16 : { ptype : 1 , size : 2 , mask : 0xffff } ,
int8 : { ptype : 1 , size : 1 , mask : 0xff } ,
float : { ptype : 2 , size : 4 , mask : null } ,
bool : { ptype : 0 , size : 1 , mask : 1 } ,
2022-05-15 22:32:35 +02:00
} ;
2022-06-16 14:02:01 +02:00
dataTypes [ "*uint32" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . uint32 } ;
dataTypes [ "*uint16" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . uint16 } ;
dataTypes [ "*uint8" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . uint8 } ;
dataTypes [ "*int32" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . int32 } ;
dataTypes [ "*int16" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . int16 } ;
dataTypes [ "*int8" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . int8 } ;
dataTypes [ "*float" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . float } ;
dataTypes [ "*bool" ] = { ptype : 0 , size : 2 , mask : 0xffff , pointing : dataTypes . bool } ;
2022-05-15 22:32:35 +02:00
var dataTypesReversed = {
2022-06-16 14:02:01 +02:00
0 : "uint/bool/pointer" ,
2022-05-15 22:32:35 +02:00
1 : "int" ,
2 : "float"
2022-06-16 14:02:01 +02:00
} ;
2022-05-15 22:32:35 +02:00
/*var numTypes = ["uint32", "uint16","uint8","int32","int16","int8","float","bool"];*/
function last ( d ) {
return d [ d . length - 1 ] ;
}
function find ( d , n ) {
for ( var i = d . length - 1 ; i >= 0 ; i -- ) {
if ( typeof d [ i ] [ n ] == "object" ) return d [ i ] [ n ] ;
}
return null ;
}
function createVars ( c ) {
var l = 0 ;
return [ Object . entries ( c ) . map ( d => {
2022-06-16 14:02:01 +02:00
if ( d [ 1 ] . type == "custom" ) {
var out = ` ${ d [ 1 ] . id } = ${ l } ; ${ d [ 1 ] . length } ` ;
l += d [ 1 ] . length ;
return out ;
} else {
var out = ` ${ d [ 1 ] . id } = ${ l } ; ${ dataTypes [ d [ 1 ] . type ] . size } ` ;
if ( d [ 1 ] . used == 0 ) return ";" + out ;
l += dataTypes [ d [ 1 ] . type ] . size ;
return out ;
}
2022-05-15 22:32:35 +02:00
} ) . join ( "\n" ) , l ] ;
}
var extrafuns = {
} ;
function execute ( data , expect , context , local ) {
var code = "" ;
var ptype = 0 ;
var doconv = true ;
let [ type , d ] = getType ( data ) ;
if ( type == "code" ) {
if ( data [ 0 ] == "defvar" ) {
var ctx = last ( context ) ;
2022-06-16 14:02:01 +02:00
var vname = data [ 1 ] ;
var vtype = data [ 2 ] ;
//var [vname,vtype] = data[1].split(":");
2022-05-15 22:32:35 +02:00
if ( ctx [ vname ] ) error ( ` Can not redefine: ${ cname } ! It is already defined! ` , ... data . pos ) ;
if ( ! dataTypes [ vtype ] ) error ( ` Unknown Datatype: ${ vtype } ` , ... data . pos ) ;
let mvar = { type : vtype , used : 0 , id : "v" + nid ++ , local : local } ;
ctx [ "v" + vname ] = mvar ;
2022-06-16 14:02:01 +02:00
let [ c , etype ] = execute ( data [ 3 ] , mvar . type , context , local ) ;
2022-05-15 22:32:35 +02:00
code += `
; defvar : executing value :
$ { c }
; defvar : Store Value
2022-06-16 14:02:01 +02:00
STA $ { dataTypes [ mvar . type ] . size | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
2022-05-15 22:32:35 +02:00
` ;
ptype = dataTypes [ mvar . type ] . ptype ;
} else if ( data [ 0 ] == "defun" ) {
2022-06-16 14:02:01 +02:00
var fname = data [ 1 ] ;
var ftype = data [ 2 ] ;
//var [fname,ftype] = (data[1]??"").split(":");
2022-05-15 22:32:35 +02:00
if ( local ) error ( ` Nested functions are currently not supported: ${ fname } ` , ... data . pos ) ;
2022-06-16 14:02:01 +02:00
if ( extrafuns [ fname ] ) error ( ` You can not declare functions double: ${ fname } ` , ... fname . pos ) ;
if ( ! dataTypes [ ftype ] ) error ( ` Unknown Datatype: ${ ftype } ` , ... ftype . pos ) ;
2022-05-15 22:32:35 +02:00
var ctx = last ( context ) ;
var funsCtx = { } ;
var args = [ ] ;
var lcode = "" ;
2022-06-16 14:02:01 +02:00
for ( var i = 0 ; i < data [ 3 ] . length ; i ++ ) {
let vname = data [ 3 ] [ i ] ;
let vtype = data [ 3 ] [ i + 1 ] ;
if ( funsCtx [ vname ] ) error ( ` You declared the Argument ${ vname } in function",fname,"twice! ` , ... vname . pos ) ;
if ( ! dataTypes [ vtype ] ) error ( ` Unknown Datatype: ${ vtype } ` , ... vtype . pos ) ;
var mvarg = { type : vtype , used : 1 , id : "arg" + nid ++ , local : false } ;
var mvarl = { type : vtype , used : 1 , id : "arg" + nid ++ , local : true } ;
funsCtx [ "v" + vname ] = mvarl ;
args . push ( mvarg ) ;
ctx [ "arg_" + vname ] = mvarg ;
lcode += `
; function copy args
LDA $ { dataTypes [ mvarg . type ] . size } $ { mvarg . id }
STA $ { dataTypes [ mvarl . type ] . size | 0x10 } $ { mvarl . id }
`
}
/ * d a t a [ 3 ] . f o r E a c h ( v = > {
2022-05-15 22:32:35 +02:00
var [ vname , vtype ] = v . split ( ":" ) ;
2022-06-16 14:02:01 +02:00
if ( funsCtx [ vname ] ) error ( ` You declared the Argument ${ vname } in function",fname,"twice! ` , ... vname . pos ) ;
if ( ! dataTypes [ vtype ] ) error ( ` Unknown Datatype: ${ vtype } ` , ... vtype . pos ) ;
2022-05-15 22:32:35 +02:00
var mvarg = { type : vtype , used : 1 , id : "arg" + nid ++ , local : false } ;
var mvarl = { type : vtype , used : 1 , id : "arg" + nid ++ , local : true } ;
funsCtx [ "v" + vname ] = mvarl ;
args . push ( mvarg ) ;
ctx [ "arg_" + vname ] = mvarg ;
lcode += `
; function copy args
2022-06-16 14:02:01 +02:00
LDA $ { dataTypes [ mvarg . type ] . size } $ { mvarg . id }
STA $ { dataTypes [ mvarl . type ] . size | 0x10 } $ { mvarl . id }
2022-05-15 22:32:35 +02:00
`
2022-06-16 14:02:01 +02:00
} ) ; * /
2022-05-15 22:32:35 +02:00
var mvar = { type : ftype , used : 1 , id : "return" + nid ++ , local : false } ;
var fun = {
type : ftype ,
code : "" ,
args ,
return : mvar
} ;
extrafuns [ fname ] = fun ;
//execute lcode
lcode += "\n;function code:\n" ;
2022-06-16 14:02:01 +02:00
for ( var i = 4 ; i < data . length ; i ++ ) {
2022-05-15 22:32:35 +02:00
let [ c , t ] = execute ( data [ i ] , data . length - 1 == i ? ftype : "any" , [ ... context , funsCtx ] , true ) ;
lcode += c ;
}
ctx [ "return_" + fname ] = mvar ;
lcode += `
; return from subrutine
2022-06-16 14:02:01 +02:00
STA $ { dataTypes [ mvar . type ] . size } $ { mvar . id }
2022-05-15 22:32:35 +02:00
RSR
` ;
let [ localvars , localL ] = createVars ( funsCtx ) ;
lcode = `
; function reserve Stackspace
$ { ( new Array ( Math . floor ( localL / 255 ) ) ) . fill ( "PSH 255" ) . join ( "\n " ) }
$ { ( localL % 255 > 0 ? ` PSH ${ localL % 255 } ` : '' ) }
; function place variable pointers
$ { localvars }
$ { lcode }
` ;
fun . code = lcode ;
code = `
LIA . $ { fname }
` ;
ptype = 0 ;
} else if ( data [ 0 ] == "let" ) {
var mvar = find ( context , "v" + data [ 1 ] ) ;
if ( mvar == null ) error ( ` Unknown Variable: ${ data [ 1 ] } ` , ... data . pos ) ;
mvar . used ++ ;
let [ c , etype ] = execute ( data [ 2 ] , mvar . type , context , local ) ;
code += `
; let : executing value :
$ { c }
; let : Store Value
2022-06-16 14:02:01 +02:00
STA $ { dataTypes [ mvar . type ] . size | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
2022-05-15 22:32:35 +02:00
` ;
ptype = dataTypes [ mvar . type ] . ptype ;
} else if ( data [ 0 ] == "+" ) {
var etypes = [ ] ;
var etypeMax = 0 ;
for ( var i = 1 ; i < data . length ; i ++ ) {
let [ c , etype ] = execute ( data [ i ] , "num" , context , local ) ;
code += `
; + : next value
$ { c }
` ;
if ( i < data . length - 1 ) {
code += `
PSH 4
` ;
}
etypes . push ( etype ) ;
if ( etype > etypeMax ) etypeMax = etype ;
}
if ( etypes [ 0 ] != etypeMax ) {
code += `
; + : converting not matching types
CVA $ { etypes [ 0 ] } $ { etypeMax }
` ;
}
for ( var i = 1 ; i < etypes . length ; i ++ ) {
code += `
; + : Pull / Add next
CAB
PUL 4
ADD $ { etypeMax } $ { etypes [ i ] } $ { etypeMax }
` ;
}
ptype = etypeMax ;
} else if ( data [ 0 ] == "-" ) {
var etypes = [ ] ;
var etypeMax = 0 ;
for ( var i = data . length - 1 ; i >= 1 ; i -- ) {
let [ c , etype ] = execute ( data [ i ] , "num" , context , local ) ;
code += `
; - : next value
$ { c }
` ;
if ( i > 1 ) {
code += `
PSH 4
` ;
}
etypes . push ( etype ) ;
if ( etype > etypeMax ) etypeMax = etype ;
}
if ( etypes [ 0 ] != etypeMax ) {
code += `
; - : converting not matching types
CVA $ { etypes [ 0 ] } $ { etypeMax }
` ;
}
for ( var i = 1 ; i < etypes . length ; i ++ ) {
code += `
; - : Pull / Add next
CAC
PUL 4
CAB
CCA
SUB $ { etypeMax } $ { etypes [ i ] } $ { etypeMax }
` ;
}
ptype = etypeMax ;
} else if ( data [ 0 ] == "*" ) {
var etypes = [ ] ;
var etypeMax = 0 ;
for ( var i = 1 ; i < data . length ; i ++ ) {
let [ c , etype ] = execute ( data [ i ] , "num" , context , local ) ;
code += `
; * : next value
$ { c }
` ;
if ( i < data . length - 1 ) {
code += `
PSH 4
` ;
}
etypes . push ( etype ) ;
if ( etype > etypeMax ) etypeMax = etype ;
}
if ( etypes [ 0 ] != etypeMax ) {
code += `
; * : converting not matching types
CVA $ { etypes [ 0 ] } $ { etypeMax }
` ;
}
for ( var i = 1 ; i < etypes . length ; i ++ ) {
code += `
; * : Pull / Add next
CAB
PUL 4
MUL $ { etypeMax } $ { etypes [ i ] } $ { etypeMax }
` ;
}
ptype = etypeMax ;
} else if ( data [ 0 ] == "/" ) {
var etypes = [ ] ;
var etypeMax = 0 ;
for ( var i = data . length - 1 ; i >= 1 ; i -- ) {
let [ c , etype ] = execute ( data [ i ] , "num" , context , local ) ;
code += `
; / : n e x t v a l u e
$ { c }
` ;
if ( i > 1 ) {
code += `
PSH 4
` ;
}
etypes . push ( etype ) ;
if ( etype > etypeMax ) etypeMax = etype ;
}
if ( etypes [ 0 ] != etypeMax ) {
code += `
; / : c o n v e r t i n g n o t m a t c h i n g t y p e s
CVA $ { etypes [ 0 ] } $ { etypeMax }
` ;
}
for ( var i = 1 ; i < etypes . length ; i ++ ) {
code += `
; / : P u l l / A d d n e x t
CAC
PUL 4
CAB
CCA
DIV $ { etypeMax } $ { etypes [ i ] } $ { etypeMax }
` ;
}
ptype = etypeMax ;
} else if ( data [ 0 ] == "print" ) {
let [ c , etype ] = execute ( data [ 1 ] , "any" , context , local ) ;
code += `
; print : executing value :
$ { c }
; print Value
OUT $ { etype }
` ;
ptype = etype ;
} else if ( data [ 0 ] == "if" ) {
let [ c , etype ] = execute ( data [ 1 ] , "bool" , context , local ) ;
let [ c1 , etype1 ] = execute ( data [ 2 ] , expect , context , local ) ;
let c2 , etype2 ;
if ( typeof data [ 3 ] != "undefined" ) {
[ c2 , etype2 ] = execute ( data [ 3 ] , expect , context , local ) ;
} else {
[ c2 , etype2 ] = [ "LIA 0" , 0 ] ;
}
var id = nid ++ ;
code += `
; if : executing value :
$ { c }
; if :
LIB 1
CMP 0 0
JNE . else $ { id }
; then code
$ { c1 }
JMP . afterif$ { id }
else $ { id } :
; else code
$ { c2 }
afterif$ { id } :
` ;
ptype = etype1 ;
} else if ( data [ 0 ] == ">" ) {
let [ c1 , etype1 ] = execute ( data [ 1 ] , "num" , context , local ) ;
let [ c2 , etype2 ] = execute ( data [ 2 ] , "num" , context , local ) ;
doconv = false ;
var id = nid ++ ;
code += `
; > : execute first
$ { c1 }
PSH 4
; > : execute secound
$ { c2 }
CAB
PUL 4
CMP $ { etype1 } $ { etype2 }
LIA 1
JB . endcompare$ { id }
LIA 0
endcompare$ { id } :
` ;
} else if ( data [ 0 ] == "<" ) {
let [ c1 , etype1 ] = execute ( data [ 1 ] , "num" , context , local ) ;
let [ c2 , etype2 ] = execute ( data [ 2 ] , "num" , context , local ) ;
doconv = false ;
var id = nid ++ ;
code += `
; < : execute first
$ { c1 }
PSH 4
; < : execute secound
$ { c2 }
CAB
PUL 4
CMP $ { etype1 } $ { etype2 }
LIA 1
JS . endcompare$ { id }
LIA 0
endcompare$ { id } :
` ;
} else if ( data [ 0 ] == "=" ) {
let [ c1 , etype1 ] = execute ( data [ 1 ] , "num" , context , local ) ;
let [ c2 , etype2 ] = execute ( data [ 2 ] , "num" , context , local ) ;
doconv = false ;
var id = nid ++ ;
code += `
; > : execute first
$ { c1 }
PSH 4
; > : execute secound
$ { c2 }
CAB
PUL 4
CMP $ { etype1 } $ { etype2 }
LIA 1
JE . endcompare$ { id }
LIA 0
endcompare$ { id } :
` ;
2022-05-16 17:45:34 +02:00
} else if ( data [ 0 ] == "loop" ) {
if ( data [ 1 ] == "while" ) {
let [ c , etype ] = execute ( data [ 2 ] , "bool" , context , local ) ;
var idbefor = nid ++ ;
var idafter = nid ++ ;
var codeinsert = "" ;
for ( var i = 3 ; i < data . length ; i ++ ) {
let [ ci , ti ] = execute ( data [ i ] , i == data . length - 1 ? expect : "any" , context , local ) ;
ptype = ti ;
codeinsert += ci ;
}
code += `
beforloop$ { idbefor } :
$ { c }
LIB 1
CMP 0 0
JNE . afterloop$ { idafter }
; loop code
$ { codeinsert }
JMP . beforloop$ { idbefor }
afterloop$ { idafter } :
` ;
} else if ( data [ 1 ] == "for" ) {
error ( "Methode 'for' will be implemented later." , ... data [ 1 ] . pos ) ;
} else {
error ( ` Unknown loop Methode: ${ data [ 1 ] } ` , ... data [ 1 ] . pos ) ;
}
2022-06-16 14:02:01 +02:00
} else if ( data [ 0 ] == "list" ) {
var ltype = expect ; //data[1];
if ( ! ltype . startsWith ( "*" ) ) error ( "list requires appropriated context to determine the Datatype requires appropriated context to determine the datatype" , ... data [ 0 ] . pos ) ;
if ( ! dataTypes [ ltype ] ) error ( ` Unknown Datatype: ${ ltype } ` , ... ltype . pos ) ;
let mvar = { type : "custom" , length : dataTypes [ ltype ] . pointing . size * ( data . length - 1 ) , id : "l" + nid ++ , local : local } ;
var ctx = last ( context ) ;
ctx [ "l" + nid ++ ] = mvar ;
for ( var i = 0 ; i < data . length - 1 ; i ++ ) {
let [ c , t ] = execute ( data [ i + 1 ] , ltype . substr ( 1 ) , context , local ) ;
code += c ;
code += `
; load $ { i } List element
LIX $ { i * dataTypes [ ltype ] . size }
SOA $ { dataTypes [ ltype ] . size | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
` ;
}
code += `
; return List Pointer
LIA $ { mvar . id }
` ;
ptype = 0 ;
} else if ( data [ 0 ] == "list-nth" ) {
var mvar = find ( context , "v" + data [ 1 ] ) ;
mvar . used ++ ;
if ( ! mvar . type . startsWith ( "*" ) ) error ( "list-nth requires Listpointer as Input." , ... data [ 1 ] . pos ) ;
let [ c , etype ] = execute ( data [ 2 ] , "uint16" , context , local ) ;
code += `
; Load list pointers
$ { c }
; calculate Byte offset
LIB $ { dataTypes [ mvar . type ] . pointing . size }
MUL 0 0 0
; Load pointer Address
LIX $ { mvar . id }
LOB $ { 2 | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
ADD 0 0 0
CAX
; fetch list - nth
LOA $ { dataTypes [ mvar . type ] . pointing . size | ( mvar . local ? 0x10 : 0 ) } 0
` ;
ptype = dataTypes [ mvar . type ] . pointing . ptype ;
} else if ( data [ 0 ] == "list-set" ) {
var mvar = find ( context , "v" + data [ 1 ] ) ;
mvar . used ++ ;
if ( ! mvar . type . startsWith ( "*" ) ) error ( "list-set requires Listpointer as Input." , ... data [ 1 ] . pos ) ;
let [ c1 , etype1 ] = execute ( data [ 2 ] , "uint16" , context , local ) ;
let [ c2 , etype2 ] = execute ( data [ 3 ] , mvar . type . substr ( 1 ) , context , local ) ;
code += `
; Load value
$ { c2 }
PSH $ { dataTypes [ mvar . type ] . pointing . size }
; Load list pointers
$ { c1 }
; calculate Byte offset
LIB $ { dataTypes [ mvar . type ] . pointing . size }
MUL 0 0 0
; Load pointer Address
LIX $ { mvar . id }
LOB $ { 2 | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
ADD 0 0 0
CAX
PUL $ { dataTypes [ mvar . type ] . pointing . size }
; fetch list - nth
SOA $ { dataTypes [ mvar . type ] . pointing . size | ( mvar . local ? 0x10 : 0 ) } 0
` ;
ptype = dataTypes [ mvar . type ] . pointing . ptype ;
2022-05-15 22:32:35 +02:00
} else {
if ( extrafuns [ data [ 0 ] ] ) {
var fun = extrafuns [ data [ 0 ] ] ;
for ( var i = 0 ; i < fun . args . length ; i ++ ) {
if ( typeof data [ i + 1 ] == "undefined" ) error ( ` Argument missing for function ${ data [ 0 ] } ` , ... data . pos ) ;
var [ ecode , etype ] = execute ( data [ i + 1 ] , fun . args [ i ] . type , context , local ) ;
code += `
; $ { i + 1 } Argument
$ { ecode }
2022-06-16 14:02:01 +02:00
STA $ { dataTypes [ fun . args [ i ] . type ] . size } $ { fun . args [ i ] . id }
2022-05-15 22:32:35 +02:00
` ;
}
code += `
; excute function
JSR . $ { data [ 0 ] }
; loading return value
2022-06-16 14:02:01 +02:00
LDA $ { dataTypes [ fun . return . type ] . size } $ { fun . return . id }
2022-05-15 22:32:35 +02:00
` ;
ptype = dataTypes [ fun . return . type ] . ptype ;
} else {
error ( ` Unknown command: ${ data [ 0 ] } ` , ... data . pos ) ;
}
}
} else if ( type == "var" ) {
let mvar = find ( context , "v" + d ) ;
if ( mvar == null ) error ( ` Unknown Variable/Expression: ${ d } ` , ... data . pos ) ;
mvar . used ++ ;
code += `
; var : load Variable
2022-06-16 14:02:01 +02:00
LDA $ { dataTypes [ mvar . type ] . size | ( mvar . local ? 0x10 : 0 ) } $ { mvar . id }
2022-05-15 22:32:35 +02:00
` ;
ptype = dataTypes [ mvar . type ] . ptype ;
} else if ( type == "num" || type == "bool" ) {
ptype = Number . isInteger ( d ) ? ( d >= 0 ? 0 : 1 ) : 2 ;
if ( dataTypes [ expect ] ? . ptype == ptype ) {
code += `
; num : Loading num
2022-06-16 14:02:01 +02:00
LIA $ { dataTypes [ expect ] . mask == null ? d : dataTypes [ expect ] . mask & d }
2022-05-15 22:32:35 +02:00
` ;
doconv = false ;
} else {
code += `
; num : Loading num
LIA $ { d }
` ;
}
} else {
error ( ` Not Supported execution type: ${ type } of ${ d } ` , ... data . pos ) ;
}
if ( expect == "any" ) return [ code , ptype ] ;
if ( expect == "num" ) {
if ( ptype == 0 || ptype == 1 || ptype == 2 ) {
return [ code , ptype ] ;
} else {
error ( ` Can not convert ${ dataTypesReversed [ ptype ] } to Number ` , ... data . pos ) ;
}
}
if ( ptype != dataTypes [ expect ] . ptype ) {
code += `
CVA $ { ptype } $ { dataTypes [ expect ] . ptype }
` ;
}
if ( doconv && dataTypes [ expect ] . mask != null ) {
code += `
LIB $ { dataTypes [ expect ] . mask }
BWA
` ;
}
return [ code , dataTypes [ expect ] . ptype ] ;
}
var code = "" ;
var context = [ { } ] ;
for ( var i = 0 ; i < data . length ; i ++ ) {
let [ c , t ] = execute ( data [ i ] , "any" , context ) ;
code += c ;
//console.log(c);
}
var [ globvars , globL ] = createVars ( context [ 0 ] ) ;
var finish = `
$ { globvars }
SHS $ { globL }
; code
$ { code }
HLT
; functions
$ { Object . entries ( extrafuns ) . map ( d => d [ 0 ] + ":\n" + d [ 1 ] . code ) . join ( "\n\n" ) }
` ;
fs . writeFileSync ( pathout , finish ) ;
console . log ( ` Finished compiling in ${ Math . round ( performance . now ( ) ) / 1000 } sec. Assembly saved to: ${ pathout } ` ) ;