Translate the program from Pascal to [any-language]

The contest is over, see the results at the end of the question.


I think many of you have seen questions consisting of a request to translate a program from one language to another. Let's show you how to do these things right! In our competition, we proceed from such a simple program in Pascal:

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.

(It's on ideone.)

The task is as follows: you must translate the program into any-language so that save as much as possible from the source code of the program. As a target language, of course, the languages of the Pascal group are excluded (Delphi, Algol, Oberon, Modula, etc., all languages in which it is used begin/end to group teams into a composite team).

You can add constructions before and after the text given in the condition, but not inside it (more precisely, you can also add them inside, but this will be considered a change - see the counting conditions below). The text itself should be changed as soon as possible less.

Limitations: The lines of the source program between begin and end must retain their meaning. They must be executed, and when they are executed, the same thing should happen in general as in the original program: readln should read the values from the console, c := a + b should add the values of two variables (or whatever it is in your language) to the third, writeln should output the correct result to the console. (This means you can't just comment out the code the original program.)

Determining the winner: Wins the code in which the source text is least changed compared to the full original version (the number of characters added + the number of characters removed + the number of characters changed), counting the lines with program and end.. The difference in large / small letters, as well as the replacement of a character with the same font (for example, Russian "c"/English "c") is considered as half a character. If two solutions have the same number of differences (for example, zero), the one with less added code (in characters) wins. If several decisions are the same and according to this criterion, the decision that gets the most votes wins (as usual, "for" minus "against").

In particular, a complete code match wins over an incomplete one, regardless of the amount of preparatory code.

In order to make it easier to check your code, try to publish a link to an online compiler with your code. The code must compile without errors (even with warnings) and work correctly in the range of input numbers from 0 to 1000.

The duration of the contest is 1 week.


To avoid discrepancies, if the rules are unclear, please ask again in the comments or in the chat dedicated to code golf.


For example, here is a non-competitive solution on plain TeX:

\newcount\tmp \newcount\c

\def\uncatcodeletters{\uncatcoderange{`a}{`z}\uncatcoderange{`A}{`Z}}
\def\uncatcoderange#1#2{%
  \tmp=#1 \advance\tmp -1
  \loop\advance\tmp 1 \expandafter\catcode\number\tmp=11 \ifnum\tmp<#2 \repeat}

\def\s{\begingroup\uncatcodeletters\shlp}
{\def~ := #1 + #2;{%
  \global\expandafter\c\csname #1\endcsname
  \global\expandafter\advance\expandafter\c\csname #2\endcsname
  \endgroup}
\global\let\shlp=~}

\def\inp{\begingroup\uncatcodeletters\inphelper}
\def\inphelper eadln(#1);{\endlinechar=-1 \escapechar=-1
  \expandafter\inphelperi\csname #1\endcsname\endgroup}
\def\inphelperi{\global\read16 to }

\def\out{\begingroup\uncatcodeletters\outhelper}
\def\outhelper riteln(#1);{\message{\expandafter\the\csname #1\endcsname}\endgroup}

\let\DEF\def \let\END\end
\catcode`r=13 \let r=\inp \catcode`w=13 \let w=\out
\catcode`p=14 \catcode`v=14 \catcode`b=14
\let~=\catcode ~`c=13 \let c=\s ~`e=13 \DEF end.{\END}

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.

(If anyone is interested, golfed option.) Compilation transcript:

~>tex golf.tex
This is TeX, Version 3.14159265 (MiKTeX 2.9 64-bit)
(golf.tex
a=5                % <-- 5 введено с консоли

b=8                % <-- 8 введено с консоли
13 )
No pages of output.
Transcript written on golf.log.

Please write your language, the number of changed characters, and the number of characters in the preparatory code at the beginning of the solution. Also, please give no more than one solution per answer.


Update: The contest is over, here are the results.

The winner is the answer @Mike, which managed to meet 78 preparatory characters, and did not change a single character in the source code.

Another the answer by the same author looks extremely elegant (connecting the Pascal syntax as an external module, hey!), and almost won the audience award, but loses in the number of characters due to its greater generality. Both solutions use a feature of the Perl language, which in its modules allows preprocessing of text in Perl by Perl itself. Powerful language, powerful syntax controls, a well-deserved victory.

Second in the list of winners - response @Qwertiy. This solution continues the idea of "getting the text as a string, processing it to get the code in the desired language, and executing eval on it", with a nice, very technical and compact implementation (regular!).

The audience Award goes to an unexpected response from @kmv. In this solution, the text of the source program is not declared as a string, but is "pulled" from the function code! (This is, formally speaking, a non-standard solution, but actually in common browsers toString() works exactly like this.)

Third place goes to the @pavel solution with the Unix shell/C combination, which dispenses with eval by replacing strings before compilation and using the C preprocessor. This approach allows you to deal with colons, which cause difficulties for the preprocessor in pure solutions in C / C++.

In general, the idea with a string and eval turned out to be the most popular, it is also implemented by the answers @edem Perl, line-by-line replacement, almost interpretation, @Red Skotina (string substitution in Python, line-by-line text adaptation, remaining within the rules, although on the edge of), @gil9red (the same, but more universally, Python), @nuts119 in C# (yes, in C# you can do eval, didn't you know?) and @Streletz in Java (interpreter from a third-party library).

The topic of interpretation continues with another solution @nuts119 in C# using DataTable as an arithmetic engine. the solution, for all its complexity, has a long-range aim at building a full-fledged interpreter.

The remaining solutions in pure C / C++ and Javascript / Typescript without eval are forced to modify the source code, although they were able to do with a minimal number of changes. Of these solutions, the best ones with one removed symbol are @kmv (C, preprocessor, using bit fields) and @Qwertiy (C++, preprocessor subtleties). Interestingly, these are both solutions remove adjacent characters from the source text: the colon is removed from := in the first case, and the sign is removed in the second case = (!).

The remaining four solutions (@Qwertiy, typescript, @pavel, C++, preprocessor (earned more votes than the winner), again @Qwertiy, javascript and @Grundy, C, preprocessor) change more characters in the source code, but are also interesting and worth your attention.

Many thanks to everyone who hosted participation in the contest!


Leaderboard: (thanks to @Grundy for adapting the script and @jfs for the idea)

function getAnswers(questionId, answer_filter, page) {
  return jQuery.ajax({
    url: '//api.stackexchange.com/2.2/questions/' + questionId + '/answers?page=' + page + '&pagesize=100&order=desc&sort=activity&site=ru.stackoverflow&filter=' + answer_filter,
    method: "get",
    dataType: "jsonp",
    crossDomain: true
  }).then(function(data) {
    if (data.has_more) {

      return getAnswers(questionId, answer_filter, page + 1).then(function(d) {
        return data.items.concat(d.items);
      })
    }
    return data.items;
  });
}

function getAuthorName(e) {
  return e.owner.display_name
}

function process(items) {

  return items.map(function(item) {
    var matched = item.body.match(/<h\d+>\s*(.+?)\s*?,.*?(\d+),.*?(\d+)\s*?(?:[.;,(].*)?<\/h/);
    if (matched) {
      return {
        lang: matched[1],
        setup: +matched[2],
        changes: +matched[3],
        link: item.share_link,
        author: getAuthorName(item)

      };
    } else {
      return {
        lang: "N/A",
        setup: "N/A",
        changes: "N/A",
        link: item.share_link,
        author: getAuthorName(item)
      }
    }
  });
}

function sort(items) {
  return items.sort(function(a, b) {
    if (a.lang == "N/A") return 1;
    if (a.changes != b.changes) return a.changes - b.changes;
    return a.setup - b.setup;
  })
}

function fillTemplate(sortedItems) {
  $('#leadership').append(sortedItems.map(function(item, index) {
    return $('<tr>').append($('<td>').html(index + 1))
      .append($('<td>').html(item.author))
      .append($('<td>').html(item.lang))
      .append($('<td>').html(item.setup))
      .append($('<td>').html(item.changes))
      .append($('<td>').append($('<a>').attr('href', item.link).text('Link')));
  }));
  return sortedItems;
}

var QUESTION_ID = 526265,
  ANSWER_FILTER = "!4*SyY(4Kifo3Mz*lT",
  startPage = 1;
getAnswers(QUESTION_ID, ANSWER_FILTER, startPage)
  .then(process)
  .then(sort)
  .then(fillTemplate);
#leadership {
  border-collapse: collapse;
}
#leadership td,
#leadership th {
  padding: 5px;
}
#leadership th {
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Таблица лидеров</h1>
<table id="leadership">
  <tr>
    <th></th>
    <th>Автор</th>
    <th>Язык</th>
    <th>Подготовка</th>
    <th>Изменено</th>
    <th></th>
  </tr>
</table>
Author: Дух сообщества, 2016-05-22

17 answers

Since the size is involved in the competition, here is another option (personally, I like it less, because it is more focused on this code):

perl, preparing 97, modified 0

Perl, preparing 78, modified 0

sub r{$_[0]=<>}
sub wr{print@_}
$_=q.

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.

;s/\b(\w)\b/\$$1/g
;s/^\S.*|.{4}n|://gm
;eval

Ideone test

What happens in the code is:

  1. Creating r/wr functions similar in action to Pascal's read/write ln.
  2. $_=q. assigns" to the default variable " all text up to the next character .. All subsequent lines work with this " default variable ", since no explicit variables are specified in them.
  3. Before variables (single-letter words) we put the sign $.
  4. Delete the lines program, var, begin, end, parts of function names (readln=r, writeln=wr), colons
  5. We execute the received text:

    r($a);
    r($b);
    $c = $a + $b;
    wr($c);
    
 19
Author: Mike, 2016-05-23 19:24:49

C++, Added 194, changed 2

Honest solution in 1 file.

#include <iostream>
#define readln(a) std::cin>>a
#define writeln(a) std::cout << a
#define var int
#define program int main(){
#define test 
struct E{
    int n;
} end;
#define integer 
#define begin 
 
program test;
var a, b, c integer;
begin
    readln(a);
    readln(b);
    c = a + b;
    writeln(c);
end.
 
n;
}
 17
Author: pavel, 2020-06-12 12:52:24

Perl, preparation (423+17) 440, modified 0

Plug-in module PascalSyntax.pm:

package PascalSyntax;
use Filter::Simple;
use Exporter;
@ISA=(Exporter);
@EXPORT = qw(var program readln writeln);
sub var(@){$_=undef for @_}
sub readln(@) {chomp($_[0]=<>);}
sub writeln(@) {print @_;}
sub program(@) {};
FILTER {
 s/:=/=/g;s/:\s+\w+//g;
 s/begin/{/g;
 s/end\.?/}/g;
 for(/var\s+(.*?);/) {
  my $t=$1; $t=~s/\s+//g;
  for (split(/,/,$t)) {
   my $var=undef;
   *{'main::'.$_}=sub():lvalue{$var};
  }
 }
};

Program:

#!/usr/bin/perl
use PascalSyntax;

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.

In this case, knowing the flexibility of perl, I wanted the code to work on its own, with minimal changes. And this is despite the fact that in perl, all variables must begin with the sign $. What was done:

  1. The Filter module is applied to the code, which allows you to change it before the compilation stage. It replaces begin and end with curly brackets (you could not to do this by declaring functions with these names). And they are deleted : because I did not find any other ways to use them (there is no "colon" operator in perl and it cannot be overloaded).
  2. The same filter parses the string var and creates functions with variable names in the main program. Returning each its own variable created in the closure. Functions have the attribute lvalue, which allows you to assign values to the variables they return (the construction c()=a()+b() becomes working, and parentheses for the functions known at the time of compilation are not required)
  3. Functions are created for the other pascal keywords (program, var, read/writeln).
 12
Author: Mike, 2020-06-12 12:52:24

JavaScript, preparation (without formatting 223+5) 228, Changed: 0

The program text can still be placed in a comment, without violating the restrictions on the task, if this text can then be extracted and executed. This solution applies this approach. The comment was used because there is no here-document syntax for strings in JavaScript.

What's going on:

  • The entire function text, including comments, can be converted to a string in JavaScript. Through f.toString() we get the text of the function, in the body of which there is a comment with the program.
  • The first replace deletes the first 4 and last 2 rows.
  • The second replace wraps the arguments for readln and writeln in quotation marks. It uses the fact that c also falls into window as a global variable.
  • The third removes the colon.

You can view here. I checked it on Firefox, Chrome.

Code with formatting:

(function (f) {
    var readln = function (x) {
        window[x] = +prompt()
    };
    var writeln = function (x) {
        alert(window[x])
    };
    eval(f.toString()
        .replace(/(.+\n){4}([\s\S]+)en[^]+$/, '$2')
        .replace(/\((.)\)/g, '("$1")')
        .replace(':', '')
    )
})(function(){/*
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
*/});
 11
Author: kmv, 2020-06-12 12:52:24

C, preparation 157, modified 1

C, preparation 159, 162, 187, 196, modified 1.

We managed to get rid of one colon by using bit fields in the structure. I couldn't think of anything for the second colon. :)

Code here.

#define test
#define var struct{int
#define integer 1;}end;a,b,c
#define begin main(){
#define readln(x) scanf("%d",&x)
#define writeln(x) printf("%d",x)

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c = a + b;
    writeln(c);
end.

a;}

After processing by the preprocessor:

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"

program;
struct{int a, b, c: 1;}end;a,b,c;
main(){
    scanf("%d",&a);
    scanf("%d",&b);
    c = a + b;
    printf("%d",c);
end.

a;}
 8
Author: kmv, 2020-06-12 12:52:24

C#, Preparing 804, Modified 0

It is not written optimally. It won't start on Mono. But you can add more" known " constructs and change the expression. Not an ideal solution for the contest :)

using System;
using System.Data;
using System.Text.RegularExpressions;
using VarIntegers = System.Collections.Generic.Dictionary<string, int>;

namespace Q526265_MyAnswer
{
    class Program
    {
        static void RunProgram(string textProgram)
        {
            DataTable dt = new DataTable();
            VarIntegers vars = new VarIntegers();
            Func<string, string> getVarName = str => Regex.Match(str, @"\(([\w]+)\)").Groups[1].Value;
            foreach (var item in textProgram.Replace("\r\n", "").Split(';'))
            {
                if (item.Contains("readln"))
                    vars[getVarName(item)] = int.Parse(Console.ReadLine());
                else if (item.Contains("writeln"))
                    Console.WriteLine(vars[getVarName(item)]);
                else if (item.Contains(":="))
                {
                    var exp = Regex.Split(item.Replace(" ", ""), ":=");
                    vars[exp[0]] = (int)dt.Compute(Regex.Replace(exp[1], @"[\w]+", m => vars[m.ToString()].ToString()), "");
                }
            }
        }

        static void Main()
        {

            RunProgram(@"
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
");
            RunProgram(@"
program test;
var number1, number2, number3: integer;
begin
    readln(number1);
    readln(number2);
    number3 := number1 * number2 - (number1 + number2);
    writeln(number3);
end.
");
        }
    }

}
 6
Author: skubarenko, 2016-05-23 14:01:55

Javascript ES6, added 100, changed 0

readln=prompt,writeln=alert;eval(`
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
`.replace(/^[pbe].*|: ?\w*/gm,"").replace(/\w+\((.)\)/g,"$1=+$&"))
 6
Author: Qwertiy, 2016-05-27 20:45:25

C++, added 252, changed 1 (and it's not a colon!)

Https://ideone.com/WxCd1s

#include <iostream>

#define program int
#define test main(){
#define var int
#define v(t) integer=a+b;u##t
#define z(t) v(t)
#define c z(__LINE__)
#define begin
#define readln std::cin>>
#define writeln(x) std::cout<<integer
#define end std::cin

program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c : a + b;
    writeln(c);
end.

get();}
 6
Author: Qwertiy, 2016-05-27 21:18:24

Typescript, added 127 120, changed 2

Sandbox

declare type integer=any
~function(a,b,writeln,end){var test,begin,u=arguments,readln=i=>u[i]=+prompt(),

program=test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c = a + b;
    writeln(c);
end.

a}(0,1,alert,{})

Javascript ES6, added 93 86, changed 3

Similar idea, but with multiple global variables:

~function(a,b,writeln,end,test,begin){readln=i=>arguments[i]=+prompt()
  
program=test;
var a, b, c, integer;
begin
    readln(a);
    readln(b);
    c = a + b;
    writeln(c);
end.

a}(0,1,alert,{})

The default value cannot be used, because it breaks the connection between arguments and the names.

 6
Author: Qwertiy, 2016-05-29 01:13:17

C, Preparation: 180, changed 5

#define program
#define test
#define begin int main(void){
#define end }
#define var(a,b,c,...) int a,b,c
#define readln(a) scanf_s("%d",&a)
#define writeln(a) printf("%d",a)

program test;
var(a, b, c, : integer);
begin
readln(a);
readln(b);
c = a + b;
writeln(c);
end
 5
Author: Grundy, 2016-05-22 15:29:04

C#

Another option, here the pascal code is already translated into c# code, which is then compiled and run.

using System;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Q526265_MyAnswer2
{
    class Program
    {
        static void RunProgram(string pascalProgram)
        {
            string className = "Program";
            Func<string, string> pascalType2SharpType = pascalType =>
            {
                switch (pascalType)
                {
                    case "integer":
                        return "int";
                }
                return "object";
            };
            var sharpProgram = Regex.Replace(pascalProgram, @"program (\w+);", m => { className = m.Groups[1].Value; return m.Result(@"
                using System;
                class $1 {
                    static void readln(ref int variable) {
                        variable = int.Parse(Console.ReadLine());
                    }
                    static void writeln(int value) {
                        Console.WriteLine(value);
                    }
            "); });
            sharpProgram = Regex.Replace(sharpProgram, @"var (.*): (\w+);", m => m.Result("static " + pascalType2SharpType(m.Groups[2].Value) + " $1;"));
            sharpProgram = Regex.Replace(sharpProgram, @"readln\((\w+)\)", "readln(ref $1)");
            sharpProgram = sharpProgram.Replace("begin", "static void Main() {").Replace("end.", "}}").Replace(":=", "=");

            object programObject = new Microsoft.CSharp.CSharpCodeProvider()
                .CompileAssemblyFromSource(new System.CodeDom.Compiler.CompilerParameters(), sharpProgram)
                .CompiledAssembly.CreateInstance(className);
            programObject.GetType().GetMethod("Main", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
        }

        static void Main(string[] args)
        {
            RunProgram(@"
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
");
            RunProgram(@"
program MyProgram;
var a, b, c, d: integer;
begin
    readln(a);
    readln(b);
    readln(d);
    c := (a + b) / d;
    writeln(c);
end.
");    
        }
    }
}

Https://ideone.com/Dt0WhE

Shorter version: https://ideone.com/jwdByx

 4
Author: skubarenko, 2016-05-22 17:35:19

Python3, preparing 423, modified 0

code_pas = '''\
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.'''

code_pas = code_pas.split('\n')
code_pas = code_pas[3:7]
code_pas[0] = code_pas[0].replace('    readln(a);','a = int(input())')
code_pas[1] = code_pas[1].replace('    readln(b);','b = int(input())')
code_pas[2] = code_pas[2].replace('    c := a + b;','c = a +b')
code_pas[3] = code_pas[3].replace('    writeln(c);','print(c)')
code = '\n'.join(code_pas)
co = compile(code,'','exec')
exec(co)

Http://ideone.com/fGsz4n

Out-of-competition option:

code_pas = '''\
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.'''
code_py = '''\
a = int(input())
b = int(input())
c = a + b
print(c)'''

code = code_pas.replace(code_pas, code_py)
co = compile(code,'','exec')
exec(co)

Http://ideone.com/L4ilJD

 4
Author: Red Skotina, 2020-06-12 12:52:24

Java, Preparation: >1500 (I can't count exactly) 1500, Changed: 0

A small example of translation from Pascal to Java and then executing the result on the fly using the BeanShell library.

I think that it is not written perfectly, because it does not have enough flexibility.

A special feature of the solution is that the Pascal syntax is also slightly preserved in the resulting Java code.

The Engine class (implements the required functionality):

import bsh.EvalError;
import java.io.IOException;
import bsh.Interpreter;

public class Engine {

//Задание с ru.SO, скопированное без каких-либо изменений
private final String sourcePascal = "program test;\nvar a, b, c: integer;\nbegin\n    readln(a);\n    readln(b);\n    c := a + b;\n    writeln(c);\nend.";

private final String classPrefix = "public class Test{";
private String methodPrefix = "public void testMethod(){";
private final String postfix = "}";
private final String readln = "private int readln(){Scanner in = new Scanner(System.in);return in.nextInt();}";
private final String writeln = "private void writeln(int a){System.out.println(a);}";
private final String engineScript = "Test t = new Test();t.testMethod();";

private String translateToJava(String source) {
    String preparedCode = source.substring(source.indexOf(";") + 1).replace(":=", "=").replace("var a, b, c: integer", "int a,b,c").replace("begin", "{").replace("end.", "}").replace("readln(a)", "a=readln()").replace("readln(b)", "b=readln()");
    String methodScript = methodPrefix +preparedCode+ postfix;
    String classScript = classPrefix + readln + writeln + methodScript + postfix;
    String result = classScript + engineScript;
    return result;
}

public void run() throws IOException, EvalError {        
    Interpreter i = new Interpreter();
    i.eval(translateToJava(sourcePascal));
}
}

Using the Engine class:

Engine en =new Engine();
en.run();

The resulting Java code that the Engine class mechanisms turn a Pascal task into:

public class Test{private int readln(){Scanner in = new Scanner(System.in);return in.nextInt();}private void writeln(int a){System.out.println(a);}public void testMethod(){
int a,b,c;
{
    a=readln();
    b=readln();
    c = a + b;
    writeln(c);
}}}Test t = new Test();t.testMethod();
 4
Author: Streletz, 2020-06-12 12:52:24

Javascript ES6, added 86 79, changed 3 (without eval)

begin=end=test=writeln=alert;with(o={a:'a',b:'b',readln(x){o[x]=+prompt()}}){

program=test;
var a, b, c, integer;
begin
    readln(a);
    readln(b);
    c = a + b;
    writeln(c);
end.

a}
 4
Author: Qwertiy, 2016-05-28 00:55:04

Python3:

code = """\
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
"""\
.replace('program test;', '')\
.replace('var a, b, c: integer;', '')\
.replace('begin', '')\
.replace('end.', '')\
.replace('    ', '')\
.replace(':=', '=')\
.replace('writeln', 'print')\
.strip()

import re
code = re.sub('readln\((.+)\);', r'\1 = int(input())', code)

exec(code)

Replacing operands / operators with similar ones. To replace readln, a regular expression is used.

 3
Author: gil9red, 2016-05-23 09:41:36

Perl, Added 304, Changed 0

p('
program test;

var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
');

sub p {
    # Получаем токены.
    while (my $s = substr($_[0], $i++, 1)) {
        $s !~ /\s/ ? $t .= $s : $t ne '' ? ((push @t, $t) and ($t='')):();
    }

    # Анализируем их, составляя текстовый аналог pascal программы для perl.
    for (my $i=0; $i < @t; $i++) {
        $e .= '$'.substr($t[$i],7,1).'=<>;' if $t[$i]=~/^readln/;
        $e .= '$'.$t[$i-1].'=$'.$t[$i+1].$t[$i+2].'$'.$t[$i+3] if $t[$i] eq ':=';  
        $e .= 'print$'. (substr($t[$i], 8, 1)).';' if $t[$i]=~/^writeln/;
    }

    # Выполняем программу.
    eval $e;
}
 3
Author: edem, 2020-06-12 12:52:24

Sh/S, Preparation: ~175, Changed:0

I don't know how fair it is or how to count it.

echo '
Dreadln(a) scanf("%d",&a);
Dwriteln(a) printf("%d",a);
Dvar int
Dtest
Dinteger
Dbegin main(){
Dend ;
program test;
var a, b, c: integer;
begin
    readln(a);
    readln(b);
    c := a + b;
    writeln(c);
end.
}' | sed 's/[.:]//g' | sed 's/D/#define /g'| gcc -x c - -o 1 && ./1

The header parameters are approximate, perhaps you can still improve. Thanks to chatik for the ideas.

 3
Author: pavel, 2020-06-12 12:52:24