գուցէ գիտէք, որ borland֊ը որ ստեղծել էր delphi֊ն, փորձեց object pascal֊ում եղած ֆիչըրները բերել c++։ ու բորլանդի c++֊ը տարբերւում ա սովորական c++֊ից նրանով, որ ունի այսպէս կոչուած closure֊ներ, կամ անոնիմ մեթոդներ։
իրականում, եթէ գալիս ես օբերոնից՝ ոչ մի տարօրինակ բան չկայ, շատ նորմալ ֆունկցիոնալ ա։
ահա օրինակ՝
type
TNotifyEvent = procedure(Sender: TObject) of object;
TButton = class
private
FOnClick: TNotifyEvent;
public
procedure Click;
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;
procedure TButton.Click;
begin
if Assigned(FOnClick) then
FOnClick(Self);
end;
procedure MyButtonClick(Sender: TObject);
begin
WriteLn('Button clicked!');
end;
procedure SomeEntryPoint;
var
Button: TButton;
begin
Button := TButton.Create;
Button.OnClick := @MyButtonClick;
Button.Click; // Outputs: Button clicked!
Button.Free;
end;
TNotifyEvent֊ը ֆունկցիայի, պրոցեդուրայի տիպ ա։ յետոյ այդ տիպի պրոցեդուրա ա կարելի ստեղծել։
Sender: Tobject ֊ը մեզ պէտք ա, որ իմանանք ով ա այդ event֊ը ուղարկել։ ինչի՞ ա ինքը TObject տիպի՝ որովհետեւ դա կլասսերի ծառի արմատն ա՝ ամէնը դրանից են ժառանգած, այսինքն՝ ամէնը կարելի ա դրան վերագրել։
օրինակ, կարելի ա էսպէս իմանալ թէ ով ա՝
if Sender is TButton then // Check if the sender is a button
begin
if TButton(Sender).Name = 'Button1' then
ShowMessage('Button 1 was clicked!')
else if TButton(Sender).Name = 'Button2' then
ShowMessage('Button 2 was clicked!');
end
else
begin
ShowMessage('Something else triggered this event!');
end;
տեսէք լրիւ օբերոնի runtime check անող IS ֊ն ա։
Button(Sender).Name ֊ը թոյլ ա տալիս կարդալ էդ կոնկրէտ կոճակի անունը։ օրինակ, կարող ես կոճակի անունը դնել Button1, իսկ կարող ես օրինակ՝ processButton։
Button֊ը իրականում ցուցիչ ա յիշողութեան մի տեղի, որ դատարկ ա։
TButton.Create֊ը լցնում ա էդ տեղը, ստեղծում ա յիշողութեան մէջ դաշտերը, կլասը, ու վերադարձնում ա էդ պատրաստուած յիշողութեանը ցուցիչ։
Button.OnClick֊ին կարողանում ենք վերագրել MyButtonClick ֆունկցիայի հասցէն։
այդ OnClick֊ը pascal֊ի property ա, որը կայ իմ իմանալով միայն այլ անդրեաս հայլսբերգի լեզուի՝ c#֊ի մէջ։
դրանից յետոյ Button.Click֊ը դա ա կանչելու։
շատ օբերոնական ա, չէ՞։ (:
ո՞նց ա դա արւում borland֊ի c++ դիալեկտով՝
#include <vcl.h>
#pragma hdrstop
class TButton
{
private:
typedef void __fastcall (__closure *TNotifyEvent)(TObject *Sender);
TNotifyEvent FOnClick;
public:
void __fastcall Click()
{
if (FOnClick)
FOnClick(this);
}
void __fastcall setOnClick(TNotifyEvent value)
{
FOnClick = value;
}
TNotifyEvent __fastcall getOnClick()
{
return FOnClick;
}
__property TNotifyEvent OnClick = {read=getOnClick, write=setOnClick};
};
void __fastcall MyButtonClick(TObject *Sender)
{
ShowMessage("Button clicked!");
}
int main()
{
TButton *Button = new TButton;
Button->OnClick = MyButtonClick;
Button->Click(); // Outputs: Button clicked!
delete Button;
return 0;
}
նախ, ահագին ոչ ընթերնելի ա, ինձ թւում ա։
յետոյ, դէ մասնաւորապէս որովհետեւ fastcall֊ը նշանակում ա որ պասկալի ֆունկցիա ա կանչելու, զի ամբողջ գրադարանը (vcl֊ը կամ fmx֊ը) պասկալով ա գրուած։
closure֊ը borland֊ի լուծումն ա որ մեթոդ փոյնթերն իմանայ this֊ի մասին։ ոնց pascal֊ում ա հնարաւոր։
property֊ով են փորձում դէ property իրականացնել։
հետաքրքիր ա, որ qt֊ն էլ ստանդարտ c++ չի՝ իրենք փաստացի նոր լեզու են ստեղծել, ու իրենց մօտ կայ moc (meta object compiler) որը յետոյ բերում ա qt֊ի կոդը ստանդարտ c++֊ի։ ու իրենք ունեն ինչ֊որ slot֊եր ու signal֊ներ որ էլի էմուլացնում են նոյն բանը՝ property֊ներ ու event֊ներ։
gtk֊ում ստանդարտ c ա, ու դա աւելի ա դուրս գալիս։
ի դէպ՝
https://norayr.am/weblog/2021/04/18/2492083/ — այն մասին ա որ embarcadero֊ն այլեւս չի կարողանում իր c++ քոմփայլերը շարունակել, զի c++ ստանդարտն էնքան արագ ա շարժւում, որ չեն ձգում։ ու հիմա փաստացի մէյնթէյն են անում llvm֊ի փաթչեր։ llvm֊ի արտօնագիրն էլ թոյլ ա տալիս որ դա անեն։ աւաղ։ (:
https://norayr.am/weblog/2021/04/19/2530704/
#ծրագրաւորում #ծրագրաւորման_լեզուներ #տէք #պասկալ #օբերոն #pascal #oberon
ես խնդիր ունեմ՝ ֆֆ֊ն եթէ փակուի, գիտի որ պատուհանը որ աշխատատիրոյթ տանի, իսկ փիջինը չի իմանում։
հետեւաբար ամէն անգամ փիջին անջատել միացնելուց յետոյ երկար դասաւորում եմ պատուհանները։
հիմա աւտոմատացրի էդ խնդիրը։
մի նիշքի մէջ ձեւակերպում եմ որ պատուհանը որ տիրոյթում լինի։ ցանկ ա, զի չգիտեմ որ տաբն ա էդ պահին բաց լինելու, ու ապա որն ա լինելու պատուհանի վերնագիրը։
սա իմ կարգաւորումների նիշքն ա՝
2:oberon spyurk khosenk մերգելեան գրադարան
2:intentionally_blank посторонним_в to_the_ocean_netters-dev ցանցառներ_նախագծում շեքսպ_արեւ_սոնա
3:#pine64 #pinetime #pinephone
3:#pinetab #pinebook
4:#ada #retro ##forth
4:#fpc #oberon #lazarus #pascal
5:#gentoo-powerpc #hellosystem #plan9 #minix #netbsd #freebsd #openbsd #gentoo
5:#maemo-leste #maemo #postmarketos #postmarketos-offtopic
6:#security #opsec
6:privacy-and-security privacy
7:dino_chat blabber_support conversations operators prosody xsf
7:##programming ##tokipona #pidgin #lesswrong
8:#socialhome #thefederation #diaspora #mastodon #scuttlebutt #indieweb
8:dishub fediverse disroot schroedingers_chat 404_English_chat support_for_chat.sum7.eu
9:#roms #ebooks
9:#tilderadio #helpdesk #anonradio
10:#soylent #politics #editorial
10:политика
11:fotografie
11:#photogeeks #darktable
11:#opensourcemusicians
11:cybersnoot
12:openhardware homebrew_server_club modding_fridays openwrt 64sprites
12:geminauts
13:onfoss floss linuxforum FSFE_community
13:#windowmaker #icewm
ամէն տիրոյթում ուզում եմ ունենալ երկու պատուհան, ու յստակ տեղում ու յստակ չափսի։
հիմա որ շրջում եմ տիրոյթներով, շատ հաճելի ա տեսնել նոյն ձեւ բաց պատուհաններ, ու խօսակցութիւնները։
սա էլ հիմնականում սկրիպտն ա՝
function find_active_tab_from_list2 {
read -a list <<< "$(printf "%s" "$@")"
local func_result=""
for i in "${list[@]}"
do
res=`wmctrl -l | grep ${i} | awk {' print $1 '}`
if [[ -n "$res" ]]
then
#func_result=$i
func_result=$res
fi
done
echo "$func_result"
}
այս ֆունկցիան վերնագրերի լիստն ա վերցնում ու գտնում window id֊ն որը պարունակում ա դրանցից մէկը։
(կարելի էր եւ window id չվերադարձնել, այլ հէնց անունն օգտագործել, բայց մտածեցի window id֊ն հաստատ չի կրկնուի)։
սա էլ մնացած սկրիպտի մասն ա՝
if [[ -z $1 ]]
then
echo "provide config file name"
exit
fi
set -x
var=0 #this is used to check for odd or not to put window on the left or right
while read line
do
wrkSpc=`echo $line | awk -F ":" {' print $1'}`
winLst=`echo $line | awk -F ":" {' print $2'}`
win=$(find_active_tab_from_list2 "${winLst[@]}")
if [ $((var%2)) -eq 0 ]
then
wmctrl -i -r $win -t $wrkSpc
wmctrl -i -r $win -e 0,150,50,800,900
else
wmctrl -i -r $win -t $wrkSpc
wmctrl -i -r $win -e 0,1050,50,800,900
fi
var=$((var+1))
done < $1
նախ ստուգում ա արդեօք կարգաւորումներով ֆայլի անունն ա ստացել, յետոյ տող առ տող առանձնացնում ա տիրոյթը տաբերի անունների ցանկից։
կանչում ա էն ֆունկցիան, ստանում ա պատուհանի համարը ու տեղաւորում այն էն կոորդինատներով որ նշած են։ յաջորդ անգամ միւս կոորդինատներով ա տեղաւորում։
կարելի ա էլի լաւացնել, որ ըստ էկրանի չափսերի աւտոմատ որոշի ոնց տեղաւորի։ դէ ըստ իմ նախընտրութիւնների, ես օդ եմ սիրում, ազատ տարածք այդ պատուհանների միջեւ եւ շուրջը։
սա էլ սկրիպտով պանակը։
#սկրիպտ #էքս #իքս #էքսորգ #իքսորգ #լինուքս #իւնիքս #փիջին #պատուհան #չաթ #էկրանահան
this is a very good blog post՝ back to basics about strings in C and Pascal. i suggest you to read it, and now i’ll tell you something else:
in Oberon, Wirth decided to give up on Pascal strings, and use zero terminated strings.
however, there is no need to run by the whole array to find out the length of the string. we don’t even need to have a separate field that holds the length՝ compiler knows the length of the static string.
thus it can do compile time tests. for example we have the following Oberon source՝
MODULE tst;
IMPORT Out;
VAR i: SHORTINT;
str: ARRAY 1024 OF CHAR;
BEGIN
FOR i := 0 TO LEN(str) DO
Out.Int(i, 0); Out.Ln
END;
END tst.
lets try to compile it՝
[2020-09-02 16:00:20] $ voc -m tst.Mod
tst.Mod Compiling tst.
9: FOR i := 0 TO LEN(str) DO
^
pos 102 err 113 incompatible assignment
Module compilation failed.
[2020-09-02 16:00:21] $
voc compiles Oberon source to C, which is very good to illustrate what happens. if we have՝
str: ARRAY 16 OF CHAR;
then the output C code will be՝
static CHAR tst_str[16];
nothing more։ no field for the length.
still, this՝
FOR i := 0 TO LEN(str) DO
will translate to՝
tst_i = 0;
while (tst_i <= 16) {
as i said we know the length at compile time. doesn’t matter if you generate C or assembly, you already know the number, you can put the number to the output assembly code as well.
when we write a function which receives strings, we should not knowt the length of the received string, we just use ARRAY OF CHAR
as an argument՝
MODULE tst2;
PROCEDURE addStrs(VAR a, b: ARRAY OF CHAR);
BEGIN
(* do smth useful here *)
END addStrs;
PROCEDURE test*;
VAR
s0: ARRAY 32 OF CHAR;
s1: ARRAY 64 OF CHAR;
BEGIN
addStrs(s0, s1);
END test;
END tst2.
therefore C code will be՝
static void tst2_addStrs (CHAR *a, ADDRESS a__len, CHAR *b, ADDRESS b__len)
{
/* here we think we can do smth useful */
}
void tst2_test (void)
{
CHAR s0[32];
CHAR s1[64];
tst2_addStrs((void*)s0, 32, (void*)s1, 64);
}
as we see՝ the function also gets the length of strings. and if we do LEN(a)
we get the length without any calculations.
now let’s see how dynamic strings work՝
MODULE tst3;
PROCEDURE addStrs(VAR a, b: ARRAY OF CHAR);
BEGIN
(* do smth useful here *)
END addStrs;
PROCEDURE test*(i: INTEGER);
VAR
s: ARRAY 32 OF CHAR;
ps: POINTER TO ARRAY OF CHAR;
BEGIN
NEW(ps, i);
addStrs(s, ps^);
END test;
END tst3.
now we hase a static string՝ s and we allocate a dynamic string with its pointer ps
.
lets assume we don’t know the size of ps^
string (^
means dereference) and we will receive the length of the allocated string as a function argument. it is not known at compile time.
first function remains unchanged, second function gets translated like this՝
static void tst3_addStrs (CHAR *a, ADDRESS a__len, CHAR *b, ADDRESS b__len)
{
/* do smth useful here */
}
void tst3_test (INT16 i)
{
CHAR s[32];
struct {
ADDRESS len[1];
CHAR data[1];
} *ps = NIL;
ps = __NEWARR(NIL, 1, 1, 1, 1, ((ADDRESS)(i)));
tst3_addStrs((void*)s, 32, (void*)ps->data, ps->len[0]);
}
the _NEWARR
is a bit more complicated function, which is a part of the runtime.
but we can understand what it does՝ it allocates a space in the heap, and the pointer ps
we get now points to the struct
, which has a data
field and len
field.
this is a runtime information, and in this case we have to keep a separate field for the length of the string.
that’s it.
#oberon #c #pascal #wirth #programming #programming-languages #programming_languages #design #implementation #vishap #voc #compiler #compilation #strings #string #heap #stack #storage #storage-management #storage_management #length
Every time a new assignment or parameter passing is made, the reference count of the String has to be increased, this is an atomic lock, and is related to memory management, so it’s there whether you’re using simple reference-counting or copy-on-write.
Under a GC, no atomic lock is required, a simple reference (pointer) has to be copied. This is very efficient, locally, but the memory management costs are just deferred to a later garbage collection phase. Since immutable strings don’t have reference to other objects, the GC for them can theoretically happen in parallel without any drawbacks (assuming the GC supports it).
So under a GC, an immutable String type makes a whole lot of sense, as implementing a copy-on-write one requires a lot of effort, and a mutable one is problematic multi-threading wise.
https://www.delphitools.info/2013/05/13/immutable-strings-in-delphi/
#pascal #string #strings #immutable_string #delphi #gc #programming
Why I use Object Pascal https://dubst3pp4.github.io/post/2017-10-03-why-i-use-object-pascal/
#pascal #programming #article #object_pascal #design
first of all, the article does not mention the most important thing - modules. pascal has modules. modules were introduced to c++ just in 2017. modules are why you can have type checks across boundaries of modules.
and pascal units are modules. if they do those loadable on demand, that would be cooler.
Pascal is very strict, so the programmer has to differ between subroutines that return values, in Pascal called functions, and subroutines that does not return something, called procedures. Functions and procedures can also be passed to variables or other functions thanks to procedural types.
well, in pascal successors the function
keyword removed, leaving just one procedure
, or to be precise PROCEDURE
because Wirth decided to make successor languages case sensitive and decrease the number of lexems.
It is possible to overload operators for specific types. With this feature, you have the power to define, let’s say, the result of the addition operation of two or more instances of the same class.
That’s one of the reasons why Wirth doesn’t like modern pascal implementations. The author tries to say - Pascal has all the features, while Wirth was trying to create a minimalistic language by following “less is more” principle.
Pascal is modular
okay, he said this. but did not connect to the type checks.
Pascal has good documentation
indeed, freepascal.org documentation is good, understandable and comprehensive.
well, for me Pascal today is like ‘better c++’, but why would i need better c++ if i have Oberon?
i will use it to write gui applications, or if i need to write something very fast and i don’t have libraries for Oboren and time to create libraries or bindings.
#pascal #oberon #modula-2 #wirth #design
— դու #pascal, #fpc ալիքներում ես, բայց #lazarus-ide ալիքում չես։ — մմ հա։ — ինչո՞ւ։ — …
#չաթ #զրոյց
omg fl studio is written with delphi.
#flstudio #fl_studio #daw #delphi #pascal
Me being a teacher had a decisive influence on making language and systems as simple as possible so that in my teaching, I could concentrate on the essential issues of programming rather than on details of language and notation.
#wirth #pascal #modula #oberon
C, Rust, Pascal and Go are the best in terms of energy consumption!
https://jaxenter.com/energy-efficient-programming-languages-137264.html
#golang #c #rust #pascal #energy #programming-languages #programming_languages #programming
very funny (:
#not_pascal #pascal #component_pascal #oberon
Various dialects of Pascal, such as UCSD Pascal, provide the separate compilation unit, called UNIT, as a half-way measure in the right direction. Unfortunately, the Pascal UNIT facility (interface portion) does not allow a physical separation between specification and implementation, which are tied together in the same compilation unit.
Because the interface section and the implementation section of a Pascal compilation unit are required to be in the same physical unit, the data structure for any Pascal data type must be completely specified in the interface portion except when only one variable of such data type is to be allowed. In such a case the data structure can be hidden in the implementation portion of the compilation unit. This restriction is rather severe. For example, only one complex number variable, only one stack variable, only one string variable, only one list variable, could exist in a program at a given time. This is unrealistic in most cases.
In the Modula-2 dynamic string abstraction presented in section 1.3, each procedure contains a parameter of type string. This permits many string variables to coexist in a program. Each individual string variable may be manipulated independent of the others. The data structure for the type string is not specified in the interface unit (definition module) because of Modula-2’s opaque type facility and the separation between specification and implementation.
To allow each Pascal procedure in the interface portion of a string compilation unit to contain a parameter of type string, the data structure for string must be completely specified before the first parameter reference to type string is given. Thus the essential feature of data hiding is lost in Pascal, even with the limited facility of separate compilation available in some dialects of Pascal.
#pascal #modula-2 #modula #encapsulation #interface
so long since we met last time, TMultiReadExclusiveWriteSynchronizer
#fpc #pascal #delphi #library
http://screamingduck.com/Article.php?ArticleID=43&Show=ABCE
#pascal
they talk a lot about pascal in comments https://news.ycombinator.com/item?id=11563451 #pascal
interest in pascal and haskell rises and fades together with study periods.
#screenshot #programming_languages #ada #pascal #haskell #study #programming
i was reading fpc-3.0 release related discussions, and apparently there is a change in perception. not many reactions like “who ever needs it?”, “bury it”, “is it still alive?” any more. apparently more than 15 years was required to realize that it’s a normal project, not worse than many others, not some outdated technology, but keeps developing, there is a community, they do interesting things, have nice solutions, and project doesn’t look like it’s going to die. it’s alive and running. (:
#community #society #free_software #fpc #pascal #lazarus #comment #project #perception
very interesting resource for those who are interested in compilers: http://turbopascal.org/turbo-pascal-internals
#internals #compiler #source #code #programming #compilers #pascal #turbo_pascal #book #analysis #reverse_engineering #research
#screenshot #freepascal #lazarus #solar_energy #code #pascal #trivial
code is here
#screenshot #freepascal #lazarus #solar_energy #code #pascal #trivial
it is an old paper and I like it a lot.
A Comparison of Ada and Pascal in an Introductory Computer Science Course http://www.sigada.org/conf/sa98/papers/murtagh.pdf
#ada #pascal #programming #teaching #education #computer_science #paper
free software aquarium management system. written in pascal.
#aquarium #pascal #freesoftware
Running 4 copies of an operating system at once
Dick explained to me that they were using an operating system from a company called Telesoft. Telesoft, headed by UCSD Pascal author Ken Bowles, was building an Ada compiler on top of its ROS (Renaissance Operating System) product. He told me (and I remember this clearly) that they had the operating system running in single user mode but that they wanted to run it in multi-user mode. At that point I was barely 21 years old. I had written a whole bunch of system-level 6502 assembler code and I had a really good ground-up understanding of the way that contemporary computer hardware worked. After studying the manual for the SUN board, I decided that I could simply break the 2MB of physical memory in to 4 chunks of 512KB each and run 4 copies of the operating system, gaining control via interrupts and device drivers.
#6502 #telesoft #pascal #ada #operating-systems #ucsd-pascal #compiler #ros #renaissance-operating-system #programming #history #computing #programming-languages #sun #intellimac #unix #msx #motorola68000 #68000 #68k #motorola-68k #ibm #stanford #research #memory
I have started a new repository: https://github.com/norayr/archaeology
Currently it contains ported to fpc sources of Eliza AI chat program, and console tetris. (:
#archaeology #culture #history #anthropology #eliza #tetris #console #pascal #fpc #freepascal #source
If Only Borland Had Stuck With Turbo Modula-2 For CP/M
Like Turbo Pascal, Turbo Modula-2 was an Integrated Development Environment including a compiler and Wordstar based editor. On top of this TM-2 added a separate linker and library manager. The most obvious initial difference is the size of an installation: TM-2 takes up 142Kb, compared to TP’s tiny 34Kb. However for this you get a lot more facilities, a bigger library and an altogether more sophisticated system.
http://techtinkering.com/2013/03/12/if-only-borland-had-stuck-with-turbo-modula-2-for-cpm/
#modula-2 #borland #pascal #cpm #retro-computing #programming
I have published Vishap Oberon compiler
#vishap #voc #oberon #oberon-2 #compiler #ofront #pascal #modula-2 #fork #github #compilers #վիշապ #օբերոն #կոմպիլյատոր #պասկալ #մոդուլա֊2 #ծրագրավորում
#story about #linking #Pascal and #Oberon: http://norayr.arnet.am/log/?p=11