Author Topic: The Imperium programming language - IPL  (Read 70507 times)

0 Members and 5 Guests are viewing this topic.

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3924
  • Country: gb
Re: The Imperium programming language - IPL
« Reply #925 on: January 19, 2023, 07:32:18 pm »
Quote
Here we go again, you actually want me to ignore you, another rude insulting rant (emphasis added by me) where you attack demons of your own making. You're ignored for abusive and demeaning  language.

So, this dude really *blames others* for his social and tecnical defects.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14607
  • Country: fr
Re: The Imperium programming language - IPL
« Reply #926 on: January 19, 2023, 07:42:53 pm »
Now that ChatGPT has been involved in this process, I think we're gonna reach the sublime!
 
The following users thanked this post: DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3924
  • Country: gb
Re: The Imperium programming language - IPL
« Reply #927 on: January 19, 2023, 08:22:42 pm »
sublime!

talking about sublime, I checked an old copy of my Dr. Dobb's Journal, and it says ROL and ROR were useful during i386 era for bit-by-bit examining a value in a way that is non-information-destructive.

Kind of bit(x)-test for intel chips :o :o :o

Then it points out something like this. Nice, isn't it?
("Safe, Efficient, and Portable Rotate in C/C++")

Code: [Select]
uint32_t rotl32a (uint32_t x, uint32_t n)
{
  return (x<<n) | (x>>(32-n));
}
That's basically where what @Jportici wrote came from :o :o :o

(yep, today I am in the mood of doing computer archeology
arche-comput-ology, or something)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: JPortici

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: The Imperium programming language - IPL
« Reply #928 on: January 19, 2023, 08:39:11 pm »
3. Array bounds checking: The language would have built-in array bounds checking to prevent out-of-bounds errors when accessing arrays.

Here I think we can support two modes, fast and slow. The fast simply ensures that the referenced element lies inside the array, it might be accessed with illegal subscripts, be the wrong element, but it is inside the array. The slow verifies each subscript against the arrays defined bounds. In a 10x10 array for example accessing [2,12] is wrong but won't corrupt system memory (only user data memory). These checks are not hard to do and some CPUs even offer instructions to assist. This capability could also be enabled/disabled at runtime, perhaps even on a per-array basis...

When passing an array to a function, the compiler should also pass the the length of the array to the function, so that the function can obtain the length of the array at the run-time.

For example, in C this needs to be done manually by introducing an additional parameter to the function. Also, any array bounds checking needs to be done manually. It is very easy to produce off-by-one array access errors in C.

The programmer should be able to enable/disable the compiler-generated array bounds checking. During unit testing, the programmer may want to enable all checks for best test coverage. For the production code, the programmer may want to disable the bounds checking selectively in some parts of the code.

10. Support for hardware-level control: The language would have support for interacting with low-level hardware, in order to allow for the precise control that is often required in embedded systems.

This needs better definition IMHO. The language does offer "bit" as a data type and supports declaring arrays of bits and various alignment options too. But is there more too this? What does "low level" really mean? I can see scope for abstract access to the stack, some operations that might allow stack walking perhaps but we soon get to target specific stuff which is undesirable.

I read this as "the programming language should have means to define and access the peripheral registers with an ease".

Typically the operations for peripheral registers are reading/writing a register, and testing/setting/clearing/toggling a bit or set of bits in the register.

The language should have support for defining bits and bitmasks for the registers, and prevent using a (wrong) bit mask defined for another register.

This whole register access-topic is quite complex, and needs careful analysis to get it right. For example, some registers may be read-only, some write-only, and some register may contain bits that are read-only, etc. It would be a good thing if the programming language had support for expressing these things, and the compiler could check for proper register and bit accesses. At this point I do not have any good ideas for this, though.

27. Static analysis: The language would have built-in static analysis tools that can analyze the code and detect potential errors, such as null pointer dereferences, race conditions, and buffer overflows, before the code is even run.

This is good, I've not thought much about this though, so this needs more definition perhaps...

This might be tricky, and I know very little about this topic. However, using compile-time static asserts/checks, and checks/asserts during runtime with preconditions, post-conditions and other checks could help conveying the information how the functions are expected to behave and what kind of parameter values functions are expecting. These run-time checks can be enabled during unit testing, and selectively turned off in the production code. The compiler should be able to ascertain that there are no unwanted side effects when performing these checks.
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #929 on: January 19, 2023, 08:41:02 pm »
Comparison Chaining

I've been reading about how some languages support comparison operator chaining. Now the grammars of most languages support it, it is a semantic question really.

Code: [Select]

if a < b < c > d then
   log("Conditions Met.");


This can be interpreted as

Code: [Select]

if a < b && b < c && c > d then
   log("Conditions Met.");


I find this quite appealing, thoughts?



« Last Edit: January 19, 2023, 08:51:44 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #930 on: January 19, 2023, 08:51:26 pm »
3. Array bounds checking: The language would have built-in array bounds checking to prevent out-of-bounds errors when accessing arrays.

Here I think we can support two modes, fast and slow. The fast simply ensures that the referenced element lies inside the array, it might be accessed with illegal subscripts, be the wrong element, but it is inside the array. The slow verifies each subscript against the arrays defined bounds. In a 10x10 array for example accessing [2,12] is wrong but won't corrupt system memory (only user data memory). These checks are not hard to do and some CPUs even offer instructions to assist. This capability could also be enabled/disabled at runtime, perhaps even on a per-array basis...

When passing an array to a function, the compiler should also pass the the length of the array to the function, so that the function can obtain the length of the array at the run-time.

For example, in C this needs to be done manually by introducing an additional parameter to the function. Also, any array bounds checking needs to be done manually. It is very easy to produce off-by-one array access errors in C.

The programmer should be able to enable/disable the compiler-generated array bounds checking. During unit testing, the programmer may want to enable all checks for best test coverage. For the production code, the programmer may want to disable the bounds checking selectively in some parts of the code.

10. Support for hardware-level control: The language would have support for interacting with low-level hardware, in order to allow for the precise control that is often required in embedded systems.

This needs better definition IMHO. The language does offer "bit" as a data type and supports declaring arrays of bits and various alignment options too. But is there more too this? What does "low level" really mean? I can see scope for abstract access to the stack, some operations that might allow stack walking perhaps but we soon get to target specific stuff which is undesirable.

I read this as "the programming language should have means to define and access the peripheral registers with an ease".

Typically the operations for peripheral registers are reading/writing a register, and testing/setting/clearing/toggling a bit or set of bits in the register.

The language should have support for defining bits and bitmasks for the registers, and prevent using a (wrong) bit mask defined for another register.

This whole register access-topic is quite complex, and needs careful analysis to get it right. For example, some registers may be read-only, some write-only, and some register may contain bits that are read-only, etc. It would be a good thing if the programming language had support for expressing these things, and the compiler could check for proper register and bit accesses. At this point I do not have any good ideas for this, though.

27. Static analysis: The language would have built-in static analysis tools that can analyze the code and detect potential errors, such as null pointer dereferences, race conditions, and buffer overflows, before the code is even run.

This is good, I've not thought much about this though, so this needs more definition perhaps...

This might be tricky, and I know very little about this topic. However, using compile-time static asserts/checks, and checks/asserts during runtime with preconditions, post-conditions and other checks could help conveying the information how the functions are expected to behave and what kind of parameter values functions are expecting. These run-time checks can be enabled during unit testing, and selectively turned off in the production code. The compiler should be able to ascertain that there are no unwanted side effects when performing these checks.

Speaking of array passing, I agree and PL/I offered all of this and more from the outset. It's a capability long overlooked yet curiously was made available in the 60s.

Any array whether it has bounds known at compile time or not until runtime, has (under the hood) a array "descriptor", metadata that describes everything about an array, any array, like:

1. Element size for use in subscript/offset calculations
2. Rank
3. Upper/Lower bound of each dimension

This can be stored as part of the memory allocated for the array (be it stack or heap). This then makes it trivial for executing code to get at this metadata using language builtin functions.

Additionally we can pass arrays to code that is "generic" by having that code declare the arrays as:

Code: [Select]

procedure sort_table (table);

   arg table(*,*,*) bin(15);

end;


that code "sort_table" can then at runtime discover the bounds of the array, different parts of the code can pass different sized arrays (but they must all be 3D).

So this is absolutely going to present, non negotiable. The use of * is very different in PL/I and C, so that can confuse some (it's original use back in the day was "wildcard").

A similar thing holds for strings, both fixed and variable length strings can also be declared as * args in code and the callee able to discern the metadata at runtime whatever length strings are actually passed.


« Last Edit: January 19, 2023, 08:53:44 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4069
  • Country: nz
Re: The Imperium programming language - IPL
« Reply #931 on: January 19, 2023, 09:17:13 pm »
sublime!

talking about sublime, I checked an old copy of my Dr. Dobb's Journal, and it says ROL and ROR were useful during i386 era for bit-by-bit examining a value in a way that is non-information-destructive.

Kind of bit(x)-test for intel chips :o :o :o

Then it points out something like this. Nice, isn't it?
("Safe, Efficient, and Portable Rotate in C/C++")

Code: [Select]
uint32_t rotl32a (uint32_t x, uint32_t n)
{
  return (x<<n) | (x>>(32-n));
}
That's basically where what @Jportici wrote came from :o :o :o

I'm sure it was well known long before Dr Dobbs.

With the definition of shifts used in RISC-V and others you don't even need the word-size dependent "32-n", just "-n" works fine.
 
The following users thanked this post: DiTBho

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #932 on: January 19, 2023, 09:20:49 pm »
3. Array bounds checking: The language would have built-in array bounds checking to prevent out-of-bounds errors when accessing arrays.

Here I think we can support two modes, fast and slow. The fast simply ensures that the referenced element lies inside the array, it might be accessed with illegal subscripts, be the wrong element, but it is inside the array. The slow verifies each subscript against the arrays defined bounds. In a 10x10 array for example accessing [2,12] is wrong but won't corrupt system memory (only user data memory). These checks are not hard to do and some CPUs even offer instructions to assist. This capability could also be enabled/disabled at runtime, perhaps even on a per-array basis...

When passing an array to a function, the compiler should also pass the the length of the array to the function, so that the function can obtain the length of the array at the run-time.

For example, in C this needs to be done manually by introducing an additional parameter to the function. Also, any array bounds checking needs to be done manually. It is very easy to produce off-by-one array access errors in C.

The programmer should be able to enable/disable the compiler-generated array bounds checking. During unit testing, the programmer may want to enable all checks for best test coverage. For the production code, the programmer may want to disable the bounds checking selectively in some parts of the code.

10. Support for hardware-level control: The language would have support for interacting with low-level hardware, in order to allow for the precise control that is often required in embedded systems.

This needs better definition IMHO. The language does offer "bit" as a data type and supports declaring arrays of bits and various alignment options too. But is there more too this? What does "low level" really mean? I can see scope for abstract access to the stack, some operations that might allow stack walking perhaps but we soon get to target specific stuff which is undesirable.

I read this as "the programming language should have means to define and access the peripheral registers with an ease".

Typically the operations for peripheral registers are reading/writing a register, and testing/setting/clearing/toggling a bit or set of bits in the register.

The language should have support for defining bits and bitmasks for the registers, and prevent using a (wrong) bit mask defined for another register.

This whole register access-topic is quite complex, and needs careful analysis to get it right. For example, some registers may be read-only, some write-only, and some register may contain bits that are read-only, etc. It would be a good thing if the programming language had support for expressing these things, and the compiler could check for proper register and bit accesses. At this point I do not have any good ideas for this, though.

27. Static analysis: The language would have built-in static analysis tools that can analyze the code and detect potential errors, such as null pointer dereferences, race conditions, and buffer overflows, before the code is even run.

This is good, I've not thought much about this though, so this needs more definition perhaps...

This might be tricky, and I know very little about this topic. However, using compile-time static asserts/checks, and checks/asserts during runtime with preconditions, post-conditions and other checks could help conveying the information how the functions are expected to behave and what kind of parameter values functions are expecting. These run-time checks can be enabled during unit testing, and selectively turned off in the production code. The compiler should be able to ascertain that there are no unwanted side effects when performing these checks.

The whole MCU register stuff is very interesting and I suspect there's room for innovation here. I was writing stuff recently on an STM32F4 board that uses SPI to interact with an attached NRF24 device. One of the bits in one of the NRF's "registers" (the status register if I recall) has a bit TX_DS and the act of writing a 1 to it sets it off!

Also many of the registers have several bit patterns that are illegal/unsupported, so somehow abstracting these kinds of things might be helpful too.

I actually wrote a lot of fiddly C to get this coded neatly, my experiences is written in this documentation, it was while working on that that I began to get frustrated that the language and tools just were not a capable as I wanted them to be, got me thinking about how to address these fiddly C limitations.

“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14607
  • Country: fr
Re: The Imperium programming language - IPL
« Reply #933 on: January 19, 2023, 09:40:06 pm »
sublime!

talking about sublime, I checked an old copy of my Dr. Dobb's Journal, and it says ROL and ROR were useful during i386 era for bit-by-bit examining a value in a way that is non-information-destructive.

Kind of bit(x)-test for intel chips :o :o :o

Then it points out something like this. Nice, isn't it?
("Safe, Efficient, and Portable Rotate in C/C++")

Code: [Select]
uint32_t rotl32a (uint32_t x, uint32_t n)
{
  return (x<<n) | (x>>(32-n));
}
That's basically where what @Jportici wrote came from :o :o :o

I'm sure it was well known long before Dr Dobbs.

Yeah. It's pretty basic. Of course it works not just with digits, but with any kind of objects in some order. So any kid with a decent IQ can probably devise that. ;D
 
The following users thanked this post: DiTBho

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3473
  • Country: it
Re: The Imperium programming language - IPL
« Reply #934 on: January 20, 2023, 10:10:37 am »
Now that ChatGPT has been involved in this process, I think we're gonna reach the sublime!

I wonder if we can let ChatGPT design a programming language
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3473
  • Country: it
Re: The Imperium programming language - IPL
« Reply #935 on: January 20, 2023, 10:12:34 am »
Comparison Chaining

I've been reading about how some languages support comparison operator chaining. Now the grammars of most languages support it, it is a semantic question really.

Code: [Select]

if a < b < c > d then
   log("Conditions Met.");


This can be interpreted as

Code: [Select]

if a < b && b < c && c > d then
   log("Conditions Met.");


I find this quite appealing, thoughts?

it may be that i use too much C but i do not want to think about precedences, even when writing other languages.
So i use parentheses
I probably still use this notation only when writing on paper
« Last Edit: January 20, 2023, 10:14:16 am by JPortici »
 
The following users thanked this post: newbrain

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #936 on: January 20, 2023, 03:44:56 pm »
Comparison Chaining

I've been reading about how some languages support comparison operator chaining. Now the grammars of most languages support it, it is a semantic question really.

Code: [Select]

if a < b < c > d then
   log("Conditions Met.");


This can be interpreted as

Code: [Select]

if a < b && b < c && c > d then
   log("Conditions Met.");


I find this quite appealing, thoughts?

it may be that i use too much C but i do not want to think about precedence, even when writing other languages.
So i use parentheses
I probably still use this notation only when writing on paper

Yes, I don't use it much myself but I was reading about the language Raku which has a huge number of operators and this is something that language offers (initially derive from Perl. Also do note, the above expression (a boolean valued expression) only involves comparison operators which all have identical precedence.

I don't want to abandon stuff that's deeply entrenched just because one can, for example I wondered whether using <= for assignment was worth considering:

Code: [Select]

dcl counter bin(15);

counter <= 123;

if counter = 321 then
   return;


That way the = becomes purely a comparison operator and assignment (which should never have even used = really) is visually distinct. This is extremely easy to do but the use of = for assign is so deeply entrenched that its of little value to introduce <= for this.

But in this case if you think about what "if (a < b < c > d)" means today in say C or C++ or Java or C#, Javascript etc it is not that useful anyway, how many of us would ever code a comparison that looks like that?

So adopting the chaining might be a net gain, the very few cases where the syntax might be used in C etc today are so few and so unusual that the gain of being able to condense all these chained compares might actually be worth it...

« Last Edit: January 20, 2023, 04:56:04 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #937 on: January 20, 2023, 07:51:40 pm »
OK namespaces have been added to the grammar now, never part of the PL/I language or C, but grammatically almost trivial to add and to parse.

A namespace can contain statement blocks or other namespaces and a source fine can contain multiple (that is, not nested) namespaces too:

Code: [Select]
namespace test;

    dcl root_ptr pointer;

    procedure outer (arg);

       dcl counter bin(15);
       dcl window bin(31);

        if counter = 123 then
           return;
        end;

    end procedure;

    procedure rerun (arg);

        call s$system.memory.allocate_virgin(10 0000:H); // 1,048,576 in dec FYI

    end procedure;

end;

namespace utility.sundry;
   
    // an empty namespace

end;

namespace s$system;

    namespace memory;

        procedure allocate_virgin(size);

            arg size bin(31);

        end;
    end;
end;

The beauty is of course that if compiling multiple source files, the various procs/funcs all "accumulate" into their respective containing namespaces.
« Last Edit: January 20, 2023, 07:54:51 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #938 on: January 20, 2023, 07:53:30 pm »
Something that hasn't come up is "enums" this is often a subject that elicits many opinions, so I'd love to hear them.

PL/I never had enums, so adding these is pretty much green field.

“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline alexanderbrevig

  • Frequent Contributor
  • **
  • Posts: 700
  • Country: no
  • Musician, developer and EE hobbyist
    • alexanderbrevig.com
Re: The Imperium programming language - IPL
« Reply #939 on: January 20, 2023, 11:01:26 pm »
Moderators: please can I stop notifications from this to thread? I've learned my lesson.
 
The following users thanked this post: DiTBho

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: fi
    • My home page and email address
Re: The Imperium programming language - IPL
« Reply #940 on: January 21, 2023, 12:06:25 am »
Moderators: please can I stop notifications from this to thread? I've learned my lesson.
See the buttons at the top right and bottom right of the entire thread: Reply, Notify/Unnotify, Mark unread, Send this topic, Print, Search?
If you see Notify, click on it, click Yes, and then it changes to Unnotify.  Click Unnotify, and Yes, and no more notifications!
(Even if new posts are made to this thread, it will not show up in the New Replies to Your Posts list.)

Edited: See my reply #947 for the corrected instructions.

The very useful Ignore list is accessible from the Profile button near the top of every page (your own profile, that is), and the Summary subsection.  Click that Summary.  In the Profile Info page, just above the Summary bar, there are three buttons: Profile Info (which is highlighted), Modify Profile, and Actions.  If you click Modify Profile, go down to the Buddies/Ignore list... and click on Edit Ignore List, you can add user names (like "Nominal Animal" or "Sherlock Holmes") to your ignore list, so you don't need to see their posts: they will just be minimised with a small link saying "You are ignoring this user." with "Show me the post" link right next to it, so you can expand and see the post if you actually do want to read the post.

Personally, I use the ignore list whenever I believe I cannot respond in an useful manner to some member.  I can be quite ornery/grumpy/sensitive about certain patterns, especially when I perceive someone is misleading others and refuses to correct their mis-advice because it would hurt their ego.  I also like to argue/debate objectively measurable things, instead of opinions, and that can look like trolling or "wanting to have the final word".  And my posts tend to be looooong, too.  So, I can understand why some members will want to ignore my own posts, too.

I tend to trim/flush the list after a month or so, though, and currently have six members in my ignore list.  I do not want to stop them from posting, it's just that their worldview/understanding/advice is so different to mine that I do not believe we can interact in a mutually beneficial manner.  Plus, in threads in e.g. Beginner forums, I can always open and read their posts and even thank them if they help others, to show that it is not their person I object to, only their output in other domain-specific threads, and still appreciate it when they help others.  This "output, not the person" thing is particularly important to me, because it is the reason I've used this pseudonym for the last decade or so.

The best way –– and I often fail to do this myself :-[ –– is to use the ignore list quetly, and later on, if one sees their posts quoted by another member with useful information, one can always revise ones opinion.  In the mean time, not having to read their drivel (or in my own case, my long-ass walls of text), will reduce any social friction and unnecessary arguments on the forum.
« Last Edit: January 21, 2023, 10:15:57 pm by Nominal Animal »
 
The following users thanked this post: Andy Watson, newbrain, DiTBho

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #941 on: January 21, 2023, 04:07:06 pm »
Moderators: please can I stop notifications from this to thread? I've learned my lesson.

Utterly astonishing remark from a purported creative, artistic mind.

 :-//

« Last Edit: January 21, 2023, 04:28:32 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #942 on: January 21, 2023, 04:27:35 pm »
This is a start on enums:

Code: [Select]
     def devices enum bin(15),
          gps = 10,
          adc,
          spi
      end;

      def folders enum string(32),
          devices = "devices",
          logs = "logs,
          dumps = "dumps"
      end;

      def rates enum,
           fast,
           medium,
           slow,
           stopped
      end;

A type specifier after the "enum" keyword is optional. An explicit assigned value resets the way later values get set, so in example 1 "adc" would be set by the compiler, to 11.

This syntax is pretty straightforward with a starting "def" (or "define" if one wants to avoid abbreviated keywords) then an identifier followed by attributes.

PL/I never had user defined types so defining enums and structures (as a type) was never factored into the grammar, this has implications which I'm now trying to clarify.

Now we have a true and interesting grammar challenge, one of the more interesting aspects of language design.

If we permit user defined types (which this language absolutely must) then we get a problem with the original PL/I grammar.

Code: [Select]

dcl mydata folders; // dcl an instance of the "folders" enum


The problem here is we lose backward compatibility. The current grammar lets us add new keywords over time, so we might want to add a new language attribute "folders" nothing to do with the above user's enum defintion.

But that would cause a problem, code like the above declaration will fail to compile identically, because it has a user defined name "folders" and that will now be interpreted as a use of the new "folders" attribute.

As the grammar stands now we can easily create identifiers named "binary" or "decimal" or "string" and never have a problem even though these are language keywords for predefined types.

The syntax for declarations is basically

Code: [Select]
<dcl-keyword> <identifer> [multiple other attributes in any order] <semicolon>
With user defined types we are introducing a second option for having an additional <identifier> in the declaration.

One way to fix this is to have another keyword, not use "dcl", any kewyord we add can then have its own syntax defined, as arbitrarily rich as we like and no backward compatibility issue.

So perhaps that's the best way...


« Last Edit: January 21, 2023, 05:21:55 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: The Imperium programming language - IPL
« Reply #943 on: January 21, 2023, 07:01:39 pm »
Well this is now neatly resolved, and in actual fact PL/I provided the solution already, although it wasn't clear at the time.

Types are created with a new "type" keyword, a type can define an enum or a structure (and perhaps other ideas too).

Then there's another variant of the declare statement using "as":

Code: [Select]
type baud_rates enum string(31);

dcl rates as baud_rates;

This solves it, no user defined type's name can every clash with some future added keyword.

Of course the full syntax of enum and structure aren't in place above, but this is a formality, the original problem is solved.

PL/I does have a "like" keyword and was used to declare structures that shared the layout of another structure, I just used "as" instead.

This kind of thing parses fine now:

Code: [Select]
      type baud_rates enum bit(8),
           first  = 1010 0011:b,
           second = 1110 1101:b,
           third  = 1101 0111:b,
           fourth = 0010 1100:b
      end;




« Last Edit: January 21, 2023, 07:16:37 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4069
  • Country: nz
Re: The Imperium programming language - IPL
« Reply #944 on: January 21, 2023, 08:24:13 pm »
Moderators: please can I stop notifications from this to thread? I've learned my lesson.
See the buttons at the top right and bottom right of the entire thread: Reply, Notify/Unnotify, Mark unread, Send this topic, Print, Search?
If you see Notify, click on it, click Yes, and then it changes to Unnotify.  Click Unnotify, and Yes, and no more notifications!
(Even if new posts are made to this thread, it will not show up in the New Replies to Your Posts list.)

No, that does not work. It controls notification emails or something, not "Show new replies to your posts", which I believe it is impossible to disable for a given thread.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11322
  • Country: us
    • Personal site
Re: The Imperium programming language - IPL
« Reply #945 on: January 21, 2023, 08:34:04 pm »
There is a way to ignore topics. I have no idea how to activate it though. In the forum profile there is a section for ignored topics and I have one topic ignored there and it works, I see no mentions of it anywhere. I think it is activated from the unread replies page (https://www.eevblog.com/forum/unreadreplies/?start=0), but you actually need to have some replies there before you can do this.

Edit: Yes in that page once the topic has new replies you can select the checkbox and click ignore button. I just tried after magic's reply and it worked. Unignore back in the profile.

The only thread I ignore is TEA one, since there is too much traffic there and it just does not stop.
« Last Edit: January 21, 2023, 08:56:19 pm by ataradov »
Alex
 
The following users thanked this post: MK14

Offline magic

  • Super Contributor
  • ***
  • Posts: 6821
  • Country: pl
Re: The Imperium programming language - IPL
« Reply #946 on: January 21, 2023, 08:47:49 pm »
It's quite arcane. I have never done it myself, but I recall somebody saying that you need to first enable "quick moderation → as checkboxes" in forum profile and then the option for ignoring topics is supposed to appear.

I don't bother, I ignore topics, posts, users etc with the scroll wheel ;)
 
The following users thanked this post: DiTBho

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: fi
    • My home page and email address
Re: The Imperium programming language - IPL
« Reply #947 on: January 21, 2023, 10:14:39 pm »
No, that does not work. It controls notification emails or something, not "Show new replies to your posts", which I believe it is impossible to disable for a given thread.
You're right.  I mixed the darn things up!

Near the top of the page, click on Profile > Summary.
In the new page, just below that, click on Modify profile > Look and Layout.

If you are ignoring users, make sure the Hide messages posted by members on my ignore list is checked.

At the bottom of the list, for Show quick moderation as select Checkboxes.

Then, you need to wait until new replies appear in threads you want to ignore.
At the top of the page, you can see the Show new replies to my posts link; this leads to the Updated topics page (for yourself); you can bookmark this if you want to check for replies to your posts.

This page lists threads with new posts.  At the right edge at the top of the topic list, you have three buttons, with the rightmost being Ignore topics.
Add a Checkmark at the right edge for each topic you want to ignore, and then click Ignore topics.
Yes, it is unfortunate that you need to wait until new replies are posted to that thread before you can ignore it, but it does work.
« Last Edit: January 21, 2023, 10:18:11 pm by Nominal Animal »
 
The following users thanked this post: MK14

Offline MIS42N

  • Frequent Contributor
  • **
  • Posts: 512
  • Country: au
Re: The Imperium programming language - IPL
« Reply #948 on: January 22, 2023, 01:25:02 am »
One of the things that is messy in assembler is using fractions in fixed point arithmetic. Floating point is fine when it is part of the instruction set, but not every microprocessor has FP.

So being able to define something as (in an arbitrary language) binary [8\8] would be nice, an 8 bit integer part and an 8 bit fraction part. Or [0\24], [16\16] etc. The code required is simple, just shift bits or add zero bytes before computation. But interpreting what goes on is not so clear. Being able to express it in the language would be helpful.

Is this already a thing, or is it too obscure to be worried about? Languages I've encountered assume int is integer (funny about that) and if fractions are thing, it is done in floating point with a floating point library if not native to the architecture.



 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: fi
    • My home page and email address
Re: The Imperium programming language - IPL
« Reply #949 on: January 22, 2023, 03:54:38 am »
So being able to define something as (in an arbitrary language) binary [8\8] would be nice, an 8 bit integer part and an 8 bit fraction part. [...] Is this already a thing, or is it too obscure to be worried about?
I have implemented something like that in Python, deriving from tuple.  Arithmetic, unary, and binary operators are just syntactic sugar on top of special methods, so that e.g. a*b is equivalent to a.__mul__(b) (or if that is NotImplemented, then b.__rmul__(a)).  (I called dividing the integral numerator and the denominator (n/d) of a number, "normalization"; with divisor always positive, and only the numerator signed.  You end up doing this basically after every operation, which makes arithmetic using such a the type surprisingly "slow".  For Python, it doesn't matter much, because it is quite slow anyway.)
If I recall correctly, I used it for prime decomposition or something like that; a simple algorithmic solution to something, closer to HPC, and not really anything I'd need on a small microcontroller.

On the other hand, a very close cousin, interval arithmetic can be very useful even on small microcontrollers (and with both integer and floating-point math).  Essentially, each number is represented by an interval, min..max.  Operations like multiplication and division yield the largest interval when applied to the arguments.

(If you continue down that rabbit hole, you can represent each number by their probability distribution, for example their Gaussian probability distribution, so that the result of the same arithmetic operations you apply to scalar numbers, yields the probability distribution of the results when all inputs and constants are also specified as probability distributions.  It can be quite useful when dealing with uncertain and fuzzy data.  You will want to choose your basis distribution carefullt, though, and compose all other distributions as sums or variants of that.  Gaussian itself is a good choice, but there are others as well.)

I am not in favour of generic operator overload or operator definition, in the sense of how e.g. C++ uses >> and << with streams, but being able to define the functions corresponding to arithmetic, binary, and unary operators, is definitely useful with custom numeric types (fixed point formats, interval arithmetic, etc.) as well as vectors and matrices (and linear algebra in general).  Exactly how this is done depends on your language and preferences, of course, but I do prefer most the model where the operator function is solely determined by the types of the arguments to the operator.  For built-in arithmetic types (number types), the functions would be provided by the compiler.  For custom types, you'd define one function per type pair (for arithmetic and binary operators) or one function per type (for unary operators).  For example:
   dfn operator_multiply(int a, vec2d b): vec2d(a*b.x, a*b.y);
   dfn operator_multiply(vec2d a, int b): vec2d(a.x*b, a.y*b);
   dfn operator_multiply(vec2d a, vec2d b): int(a.x*b.y - a.y*b.x);
   dfn operator_divide(vec2d a, int b): vec2d(a.x/b, a.y/b);
   dfn operator_divide(int a, vec2d b): forbidden;

For optimization, it is quite important that the language has a concept of "pure" functions: functions whose return value depends only on their arguments, and have no side effects, so that they can be evaluated at any point and always yield the same result – and that calls to such functions can be freely rearranged, cached, and even omitted.  (The effect of such a concept for a compiler is easy to see, for example in Fortran 95 'forall' loops.  Also, GCC and Clang implement this even for C via the const function attribute, __attribute__((const)).)



What I wonder myself, is whether developers would be confused with different "kinds" of functions –– like operators above, or say accessors that can only access their own object, but are otherwise "pure"/"const".  If you look and ask around, it is clear that even the distinction between Fortran functions and subroutines (the former returning a value, the latter not returning anything) makes people ask questions.  Would it be better to have separate function 'kinds', or just have attributes specifying their expected (and compile-time verified) properties?

I ended up in details like how to deal with say "pure" function when supplied with a parameter of a "volatile" type.  You can solve it at the model level (ie. "operator functions will have their arguments passed by value" in which case the volatility of the value nullifies reuse but makes the same function "work"), or you can have a way to state parameter type requirements, somewhat akin to old K&R C function or Fortran 95 function or subroutine parameter definition.

The rabbit hole went so far for me that I looked into the possibility of having the object file format support the definition (down to which register a parameter is passed in, as well as its type) of each parameter.  At some point it gets too far, as in requiring completely new file formats for the toolchain to work on, and not just a completely new toolchain...  ::)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf