Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Dimava

Pages: [1]
1
Code: (clickermann) [Select]
print("Hello, world!")

FOR($a=0,$a<50)
   $c = char($a)
   $v = $c ! $c
   if (strlen($v) ! 1)
      print("[",$a,"] ",strlen($v)," '",$c,"' ",$v)
   end_if
END_CYC

halt

Очевидно, данная программа должна выводить ничего (она сравнивает символ с самим собой, и проверяет что получился 0)

Однако она выводит
Code: (clickermann) [Select]
16:57:46 Hello, world!
16:57:46 [34] 7 '"' """!"""
16:57:46 [35] 5 '#' "0!"0
16:57:46 [39] 7 ''' "'"!"'"

Скорее всего это связано с тем, что перед eval-ом строки кода текст не escape-ится

2
Вот тот мой препроцессор (работает только в браузере): https://output.jsbin.com/rafaqey ( код - https://jsbin.com/rafaqey/edit?js,output )

А вот что оно делает (там этот же пример)

Code: (clickermann) [Select]
#preprocessor "please_make_this_dll.dll"            #preprocessor "please_make_this_dll.dll"
                                                       
// пример                                           // пример
                                                   
// локальные переменные $x и $y - имена поменять    // локальные переменные $x и $y - имена поменять
sub(fn1, $x, $y)                                    sub(fn1, $_fn1_1, $_fn1_2)
   // возвращаемое значение - имя поменять             // возвращаемое значение - имя поменять
   $ret = $x * $x + $y * $y                            $_fn1_ret = $_fn1_1 * $_fn1_1 + $_fn1_2 * $_fn1_2
end_sub                                             end_sub
                                                   
for ($x = 0, $x < 5)                                for ($x = 0, $x < 5)
   for ($y = 0, $y < 5)                                for ($y = 0, $y < 5)
      // вызов функции - сохранить возвращаемое           // вызов функции - сохранить возвращаемое
      //     значение во временную переменную             //     значение во временную переменную
      $s = $s + fn1($x, $y)                               fn1($x, $y)
   end_cyc                                                $_temp_1 = $_fn1_ret
end_cyc                                                   $s = $s + $_temp_1
                                                       end_cyc
                                                    end_cyc

                                                   
// пример 2                                         // пример 2
                                                   
sub(fn2, $i)                                        sub(fn2, $_fn2_1)
   // возвращаемой значение - имя всегда $ret          // возвращаемой значение - имя всегда $_fn2_ret
   $ret = $i * ($i + 1)                                $_fn2_ret = $_fn2_1 * ($_fn2_1 + 1)
end_sub                                             end_sub
                                                   
// развёртка функций должна поддерживать            // развёртка функций должна поддерживать
// многократную вложенность                         // многократную вложенность
$v1 = fn2(1) + fn2(fn2(fn2(fn2(1))))                fn2(1)
                                                    $_temp_1 = $_fn2_ret
// встроенные функции не должны развёртываться      fn2(1)
$v2 = fn2(cos(sin(fn2(1))))                         $_temp_2 = $_fn2_ret
                                                    fn2($_temp_2)
                                                    $_temp_3 = $_fn2_ret
                                                    fn2($_temp_3)
                                                    $_temp_4 = $_fn2_ret
                                                    fn2($_temp_4)
                                                    $_temp_5 = $_fn2_ret
                                                    $v1 = $_temp_1 + $_temp_5
                                                   
                                                    // встроенные функции не должны развёртываться
                                                    fn2(1)
                                                    $_temp_6 = $_fn2_ret
                                                    fn2(cos(sin($_temp_6)))
                                                    $_temp_9 = $_fn2_ret
                                                    $v2 = $_temp_9
                                                   

3
С помощью препроцессора вполне возможно сделать хоть и немного кривые, но функции.
С локальными переменными и возвращаемыми значениями.

Code: (javascript) [Select]
s = `

sub(ar, $i, $j)
$ret = $arr[$i+10*$j+11]
end_sub

ar(1, 2)

$v1 = ar(1, ar(2, sin(3))))

$v2 = sin(ar(2, sin(3)))

$v3 = ar(ar(1, 2), ar(3, 4))

`;


a = s.split('\n');
b = [];

localvars = new Map();
subname = ''
subnames = new Set();

// todo: make both 'SUB' and 'sub' support
a = a.map(s=>{
if (s.startsWith('sub(')) {

subname = s.match(/\(\s*(\w+)/)[1];
subnames.add(subname);

localvars = new Map();
localvars.set('$ret', '$_' + subname + '_ret');

return s.replace(/\$\w+/g, s=>{
localvars.set(s, '$_' + subname + '_' + localvars.size);
return localvars.get(s);
}
);
}

if (s.startsWith('end_sub')) {
localvars = new Map();
return s;
}

return s.replace(/\$\w+/g, s=>{
return localvars.get(s) || s;
}
);
}
)

a2 = [];
tempn = 0;
for (let s of a) {
if (s.match(/^\s*(sub|for|while|do|if)\s*\(/)) {
a2.push(s);
continue;
}

let ws = s.match(/^\s*/)[0];

// todo: make "(" string support
let temps = []
for (let i = 0; i < 10; i++) {
s = s.replace(/(\w+)\([^()]*\)/, (s, fname) => {
let tempname = '$_temp_' + (++tempn)
let o = {type: 'call', s, fname, n: tempn, tempname};
o.id = temps.push(o);
return tempname;
})
}
let inlines = new Map();
for (let o of temps) {
for (let i = 0; i < 10; i++) {
o.s = o.s.replace(/\$_temp_\w+/, s => inlines.get(s) || s)
}
if (subnames.has(o.fname)) {
a2.push(ws + o.s);
a2.push(ws + o.tempname + ' = $_' + o.fname + '_ret');
} else {
inlines.set(o.tempname, o.s)
}
}
for (let i = 0; i < 10; i++) {
s = s.replace(/\$_temp_\w+/, s => inlines.get(s) || s)
}
a2.push(s);


}

s = a2.join('\n')

console.log('%o', s);


Из
Code: (clickermann) [Select]
sub(ar, $i, $j)
$ret = $arr[$i+10*$j+11]
end_sub

ar(1, 2)

$v1 = ar(1, ar(2, sin(3))))

$v2 = sin(ar(2, sin(3)))

$v3 = ar(ar(1, 2), ar(3, 4))
генерирует
Code: (clickermann) [Select]
sub(ar, $_ar_1, $_ar_2)
$_ar_ret = $arr[$_ar_1+10*$_ar_2+11]
end_sub

ar(1, 2)
$_temp_1 = $_ar_ret
$_temp_1

ar(2, sin(3))
$_temp_3 = $_ar_ret
ar(1, $_temp_3)
$_temp_4 = $_ar_ret
$v1 = $_temp_4)

ar(2, sin(3))
$_temp_6 = $_ar_ret
$v2 = sin($_temp_6)

ar(1, 2)
$_temp_8 = $_ar_ret
ar(3, 4)
$_temp_9 = $_ar_ret
ar($_temp_8, $_temp_9)
$_temp_10 = $_ar_ret
$v3 = $_temp_10


Если кто может перевести в dll (сам на подходящих языках плохо пишу), пожалуйста скомпилируйте.

Pages: [1]