Bare C

breaking limitations in life, taking the brackets out of programming
Written entirely by Adam Pickett (with credits to original developers of C)

Please read the disclaimer at the bottom, since I don’t have the money or power to get a grant for ANYTHING.

**   If you’re going to use this for any reason, like building a compiler (difficult for most of people), or something else of more value than personal use, then at least give me credit.

Similar to C++, this self-programmable language contains scripting elements that can compile or create other languages.  It might (and who wouldn’t emphasize “might”) be the most advanced, most constructive (and really powerful) programming language available.  It might also be the fastest to learn, since it’s closer to spoken language, though it is still flexible at a low level.
Programming can make you a nerd, so let the compiler do the work, instead; so you don’t need to put in the same stuff, over, and over.......

-- putting a compiler with this self-programmable language on idle, and you could generate an A.I.
(artificial intelligence)

Some symbols on this page may not show up correctly due to the limitation on the number of mathematical symbols HTML has.

Names with an asterisk (*) mean that they are not optional or existent in C.
There may be more names that aren’t applicable to other languages.

And, what kicked off this language in whole:

“bare” structures.

“Bare” structures are the results of leaving out the brackets, and in simplifying the whole equation, it bends the rules.

This language is heavily object-oriented, so everything has no non-specific order.  

Putting an identifier before a structure or an identifier that holds the type of a structure would force the compiled program to translate every entry within the structure to fit.
-- excellent for converting endian formats between platforms
Functions, Macros, and Commands, all are parsed in a run-on fashion, using identifiers to form, what is called, “glue,” taking every word, as it comes, and acting differently only on the defined concepts.

Every symbol has it’s own mathematical significance.


Brackets are not needed in commands, just as long as the “end” identifier is found on the ending line.  The name of the label is also allowed.
   Sample- Example code: (whatever)

int initialize()
{
    if (something)
    {
        loop
        {
            -- code
            whatever(something);
        } until something;
        -[
            the brackets are not needed for routines that have only one line
        ]-
        loop until something
    }
    -- code
}

function int main() -- the term “function” is needed for Bare functions
-- (the English term for routines or functions that end with the English term “end”)
  if (this) then -- “then” is required
    loop until something for -- again, specific commands, like,
    -- loops and conditionals require the English terms that set up
    -- where the brackets left off are required for Bare functions
    end loop; -- “loop” is not needed, but it helps the user know what’s end ing
  end if; -- “if” is also not needed
  whatever();
end main; -- the label “main” isn’t needed, but allowed if it matches a relative name
-- another relative name, that can be used in main’s place, is “function”

-- neither brackets nor “end” is needed for routines that have only one line
function int whatever(done.b)
    -[ more code ]-;

See the resemblance to HyperTalk? Well, HyperTalk can be compiled by replacing and ignoring certain identifiers, like, telling the compiler that the semi-colon (;) is now the “end of line”, and ignoring “loop”.

The structures

struct the_sound (global FLAGS.stereo) ? {left.channel, right.channel} : {mono.channel};

Conditionals in structures?
Yep. Just like Rez files, my programming experience has led me to take advantage of the concept, and put it into the language.
What’s with the “global” thing?
To tell the compiler where it’s coming from without having to define a “class”.
Dots for the thingamajig thing?
What?! Oh, the Type Record.
count.l, the_sound[count+1];
Why is “count+1” in the array for “the_sound”?
That sets the number of “the_sound’. This is called a “Variable Sized Array”.
Calling “sizeof(the_sound)” would require calculation code in the program.
Calling “class(sizeof(the_sound))” would return “variable”.
What’s the “l” for?
The post fix, “l,” defines “count” as a Long integer (32 bits on low end computers).
 NOTE: Structures are bit aligned, not byte aligned. Multiple byte alignment can be done with the “align” object, whenever necessary, and can be done automatically by the compiler or added using high level code.

Structure size definitions

Putting a number in parenthesis directly after a structure name within the definition sets the size of the structure, in bytes.  If the structure definition is not byte aligned, then the packed contents is shifted to the right to force alignment.  Size definitions are required if the definition of the structure, itself, is not available.
This can be done using the import command:

import name(size)

Here’s the list of all of ’em:

(text)
c, char, character
u, unicode
acts as a compiler defined character, but understood as a part of text
(integer)
b, byte8 bits, self aligned
i, int, integercompiler defined size
h, halfword, shortat least 16 bits (compiler defined)
w, word, longat least 32 bits (compiler defined)
d, doublewordat least 64 bits
q, quadwordat least 128 bits
o, octawordat least 256 bits
(floating point)
f, floatat least 32 bits
x, double, extendedusually either 64 or 80 bits
l, long floatat least 96



One extra thing about sized records, is that they can be formed into strings without having to use arrays, just by using it’s plural name or adding ‘string’ to the end of an object definition.
bs, ps, pstring1-byte length string -- local size.b = sizeof(string), string.b[]
cs, cstringnull termination length -- terminator '\0' text.b[]
ws, wstring2-byte length -- local size.h, string.b[size]
.....
String Concatenation
  Like in Java, the plus character (+) concatenates strings -- but in a low-level approach.




The default numeric type can be set using the “numeric” directive
prefixed
or dDecimal (default)
or 0x or hHexadecimal
0 (zero) or oOctal
% or b*Binary
'..'Literal
post fixed
d*Decimal
h*Hexadecimal
o*Octal
(preferenced)
fFloating Point
lLong Extended
uUnsigned
(high level - case sensitive)
KKilo (*1e+3) or (<<10) depending on type
MMega (*1e+6) or (<<20) " "
GGiga (*1e+9) or (<<30) " "
TTerra (*1e+12) or (<<40) " "
QQuadr (*1e+15) or (<<50) " "
mmilli- (/1e-3)
µmicro- (/1e-6) -- this is a “token”
nnano- (/1e-9)
ppico- (/1e-12)

Examples:

32456UL
means a unsigned 32 bit integer “32456” but if the “L” wouldn’t be there then the value may be recognized as a 16 bit integer (because it is within the range of -32768 and 32767).

(scale methodizing)

byte store[5M]
is five megabytes for “store” -- whew.

farads[5p]
if the size does not refer to a byte size, then it’s toward a three zero magnitude

88 = d88 = 88d = #88 =
0x58 = 58h = $58 = h58 =
b1011000 = 1011000b = %0101 1000 =
0130 = o130 = 130o




A symbol before an identifier changes it’s value within the expression, but if the symbol comes after it, then the value of the identifier gets affected afterward.

Trailing single

arithmetic self modifiers
-Negate
+*Absolute ValueTakes the negative sign off if existing
(does nothing on unsigned values)

NOTE: unlike C, self expressions change themselves in post modifying mode
Examples:

~x;  the bits in “x” are inverted
...1+(y-)  ... Negates ‘y’ after the rest of the expression is evaluated
...x+(y+)  ... ‘y’ becomes it’s absolute value after it’s current value is evaluated in the expression

Leading single
boolean
!Notsets to non zero if zero and vice versa
binary
~Notinverts all bits in the expression
#*Countretrieves a fundamental count -- can use plural names!
addressing
&Effective address
@*At Indexa temporary index of an array

Temporary indexing eliminates the tiresome method of having to recreate a pointer for an array, time, after time. While a variable pointer only uses the stack or one of the few registers available, “At” indices try to use all they can, since they’re temporary

WARNING: “At” temporary pointers get destroyed once they’ve become irrelevant.

Example:
    periodic_element mixture[5] -- five maximum
    @mixture = 1; -- sets the temporary index pointer to 1

    -- this destroys “@mixture”
    periodic_element *index = &mixture;


Dual

arithmetic
-Subtract
+Add
or n(...or 2π MultiplyOnly tokens can be used in the third method.
**Power(available in other languages)
/Divide
//Section
%Division Remainder or Modulus
::*Base magnitude Returns the magnitude (or number of digits) of a value according to the base given. The equivalent of a truncated logarithm.
boolean
&&Andnon zero only if both
||Ornon zero if either
^^non zero if only one of either
(comparison)
<Less than
>Greater than than
<=  or  ≤Less than or equal
>=  or  ≥ Greater than or equal
!=  or  <>  or  ≠ Unequal or Not equal
binary
|    OrEach bit set to whether any is set at the index
&    AndEach set to whether both at the index are set
^Exclusive Or Each set to whether only one out of both at the index are set
~ExchangeExchanges two containers
~+Add and ClipAdds a mask (the second operand), then clips the value by setting the bits of that value, given the mask, to zero
&^*Bit Mask each bit specified by the gate bits (one affects that bit but zero doesn’t)
Example:
x &^ y : 0x1D
-- Only ones in 0x1D (11101 in binary) get set to the value of the
-- according bits in “y” for the value within the expression

<<    Shift Left/Up The bits within storage are shifted away from the “low” end and clipped, clearing the void
>>    Shift Right/Down The bits within the container are shifted toward the low end and clipped leaving the most significant bit value filling the void (clears void if unsigned)
<~    *Rotate Left/UpThe bits within the container are shifted through the most significant bit and regained at the opposite end
~>    *Rotate Right/DownSame as “Rotate Left” but in the opposite direction
Bi-directional self modifiers (singular symbol + equal)
+=    Add to
-=    Subtract from
~=    Inverse AND - same as “... &= ~(...)”
....

NOTE: incrementing, decrementing, squaring are really a self modifier without an expression, filling in the gap with either one or two (depending on whether it would do anything).

Examples:

x+=;      -- adds 1 to “x” by 1
y*=;      -- Squares “y”
y = =+x;  -- adds 1 to “x” after setting “y” to “x” (notice the symbol’s in reverse)


indirection variable Pointer with address increment (similar to assembly)

-- Must have the pointer variable in parenthesis

Post increment

*(aptr)+  or  *(aptr+=)
Pre increment
*+(aptr)  or  *(=+aptr)
Post decrement
*(aptr)-  or  *(aptr-=)
Pre decrement
*-(aptr)  or  *(=-aptr)

NOTE: different sizes can be used by attaching a type record, such as “*(aptr.h)+” The Effective address symbol can also be used with it (&*(aptr)+)


- not to be confused with C’s double character symbol (*aptr++)

*aptr+=    adds 1 to the value at address aptr

Pointers or arrays modify the index of it:

@color-    negates the index, which results in the index subtracting from the opposite end

Example:
currency bills[1...4]; -- four bills of different value
@bills = 1; -- sets the index to the first
@bills-;    -- flips it around to wind up at 4

*index+;    -- will correct the pointer if it is out of bounds

NOTE: “overflow +aptr” will return a boolean on whether it is bad pointer




Only a certain number of compilers do bit fields. Separated by a colon (:), they are a designated “field” of bits to represent only themselves, within the byte space.

Old fashioned Structure

struct
{

    ...
    size object:width, object:width....
    ...
}
(bare)
struct structurename .... object:width, object:width....


NOTE: a “U” or an “S” before the number represents the sign (the default is usually unsigned)

Expressional
  object{offset:width}

Examples:

struct hex hi:u4, lo:u4;
-- Splits whatever container that is defined as a “hex” into two unsigned four bit
parts (or nybbles)

z = y+x{1:3};
-- Takes the bits after the first within the “x” container.
-- An error will occur if the specified field is too large, has a negative field width,
or does not exist.



Structured
[count] a count (indexed at 0)
[a..b] from a to b (from Pascal) if ‘a’ is zero, then the array will act as a single count
[xxx][xxx] matrix

Definition
{a,b,c...,z}    entries to make up the storage

NOTE: unlike C, arrays can be put on bit fields and register variables


Numbered Record

   For multiple names within a structure
Sample (from the HyperCard stack format):

stackFormat.h =
  enum
  {
      invalid,
      preRelease.1 .. version.1 = 8,
      preRelease.2, version.2 = 10 .. newer
  };

myFormat.h = strict   -- `strict' inhibits the usage of the following terms in other means
  enum
  {
      who_knows,
      whocares,
      get_away
  };



-- or //to the end of the line (!!)
-[ ... ]- or -]extended comment



Ahhh... now we get to the “loop” command.  The high level magic for generating high level loops.  Math functions, even trigonometric functions, can be written into ONE line!
Sample macro code for square root:
loop with (1<<(s::)/2) ratio 2 (s/result) until +delta≤1;

The “with” parameter (1<<(s::)/2) means the result starts with a bit magnitude of half the scale of the input.  The “ratio 2” means that the result is only affected by the code by one half.  And the “until +delta≤1” means that the positive (absolute value) difference calculated of each result must be at most one fraction.
This is the optimized equivalent of the Newton Method of finding the square root. It is not needed, since it is built in to the Bare languagel the root symbol with no second operand, “s*/;”.



Putting objects within brackets after an identifier (with the exception of structure and union definitions) means that whatever objects that are in the space between the brackets are of property of the identifier.

For example:
stuff_in_my_pocket
{
    copper coin;
    plastic button;
}
“copper coin” and “plastic button” are now properties of “stuff_in_my_pocket”.
Because “coin” is set up only with “stuff_in_my_pocket copper”, “coin” is not defined by itself.  Because of this, “coin” by itself is yet unrecognized, and not a property of “stuff_in_my_pocket”; neither is “button”, for the same reason.



Putting a colon after an ‘enum’ instead of brackets means that the names that follow represent a structure field as an unlimited sized integer, only going from bottom to top.  In other words, it’s enumeration that represent values of a power of two.

For example:
ThingFlags enum:
    something,
    another;
something’ points to the least significant bit of ‘ThingFlags’ (bit zero), and ‘another’ to bit one.



Using only symbol that represents comparison (a.k.a inequality) act in the condition for which that symbol would act toward the previous expression.

For example:
if (3<4) doThat();  if (>) doThis();
return (a==b) ? 0 : ((>) ? 1 : -1);
b = a, positive = (>);       -- comparison with zero

The previous result must not be void, or else it won’t make sense to the compiler, and an error will result (duh).



Putting a type after a variable creates a keyword, and the parameter setup becomes more flexible.

For example:
-- (somewhere along the text, maybe in a header)
typedef tablespoon Fixed32;   -- ‘Fixed32’ is already defined as 32:32 bits for high accuracy precision
fixed point values

int water(amount tablespoons);    -- plural names are acceptable

void fill_it_up()
{
    water(amount 3);
    water(amount 3 tablespoons);   -- the same as (tablespoons)3 or tablespoons(3)
}

Keywords can be used in any parameter setups.  The can even be put in macros to set up variables!  
In the case that at least one keyword is in a parameter setup, if any of the other keywords are missing, a warning will result, to notify the user that the setup may have other problems -- it might not supposed to be like that.



command routines

if  or  do..if

(high level - can be used in structures and macros)
These are predefined in the language, and are temporarily removeable.
loop  or  repeat  or  do..[condition]
   -- can be used to make the ‘for’ loop in C
 uses ‘until’ or ‘while’ for dependency in continuing the loop,
 ‘continue’ and ‘reiterate’ to reiterate the loop,
 and ‘leave’ (not ‘break’) for interruption of the loop.
 ‘reiterate’ will start the same iteration over again (be aware that it might cause the loop to reiterate infinitely)
switch  jump to the case of value being equal to...
 uses ‘break’ for finishing or interrupting the switch (!!)
    -- it’s not limited to integers
factor (!!) jump thru the cases of being a factor of...
 also uses ‘break’ for finishing or interrupting the factoring
    -- it’s not limited to integers

 

structure elements

ignore  or  unused   or  unknown
align

format defined attributes

fullto specify that all bits in the container must be set
halfto specify that a boolean must have at least half of the bits set -- for the possibility of data corruption
head or headerto declare that it is a header
tailto declare that it goes at the end of a structure
trailto specify that the symbol goes after the object
groupputting multiple objects into one
stackedeverything is on the stack
autocertain objects, especially the stack, get automatically reset
reverseorders stack parameters in reverse direction
the C modifier “pascal” would be the equivalent of “stacked auto reverse”
macroSets up parameters for an op code, or series of op codes, that require more than parameters getting pushed onto the stack.  Uses reusable temporary stack space
labelNames a macro with a string (can have spaces) for reference. Text after the first semi-colon within the text (;) is interpreted as a comment
dim or dimensionas in, co-ordinates
sizeis the size of the near individual - can be pointed elsewhere
offsetsets the amount of an element until a point
Can also set a point within a structure
magnitudefor both scale and floating point architecture
frac  or  fraction for both integer and floating point architecture -- either [-1.0,1.0] or [0,1.0)
anglekeeps the value within the modulus
tokenprivileged symbol, like ‘µ’ for micro-
signaturea literal can define a structure!
univ  or  universal from Pascal
alt  or  alternative instead of having to use typedefs all of the time
pack to force certain commands like switch to use a bitfield lookup table
Can go on to make....
terminatorsized identifying termination
coherencyhow much is understood or not broken up
failsafein case of error or unwanted hackers
compressorcompression format or high level technology
protectorprotection format or high level technology
lutlook up table format - so you don’t have to manually calculate each one
parserexactly that
randomizer(ditto)
(etc.)

-- you can keep adding more, and more until your hard drive and memory space fills
and no more having to build functions for simple operations; let the compiler do it.

Format definitions can be inlined for debugging or compression
(maybe be done automatically by the compiler)

relative attributes

elem or element or fundamental class warfare!! -- no, identifier
noneno element -- must be defined to be used
all, eachglue
for, with or  using or  given “loop” and “macro” glue
error, delta or  δmath
index
firstindex to an array -- DUH
last(ditto)
nextindex to array and/or loop iteration
ptr, pointer, handle, handleralso accessible by using the “class” function
(so you don’t have to look at the header files to know what the-
ratio, from, to, while, untilfor the “loop” command - one liner? Easy!
an “element” defined loop depends on the size of the element
leading(identifies from “lead”)
trailing(identifies from “trail”)
heading(identifies from a header)
failurein response of a function
overflow or clipped
protectedgoes beyond a “const” at protecting data
scanned
endianendian byte order
BCDBinary Coded Decimal (case sensitive)
cherishedokay... maybe I’m going too far

NOTE: Relative Attributes that aren’t defined to the compiler can’t be acted upon, but can still
be used as identifiers.
Example:

float width x, height y;
-- ‘width’ and ‘height’ are not recognized, but they are still parsed without error
-- assuming they are to seperate their types from other variables

float   x;

x = thing.x;
-- this will generate a warning, due to the fact that
-- x is defined to be only a ‘float’, and not a ‘width float’


high level single array functions
(using the “loop” command)
largest()  or  max()
smallest()  or  min()   Identifiers: lowest, highest
pin()to keep the middle value within boundaries
arithmetic standard
product()
sum()
mean()  or  average()(sum/count)
median()middle number (or average of the remaining middle numbers)
mode()most occurring (or average of the same most occurring)
lcd()lowest common denominator
factors()builds an array of the prime factors of a number or returns an index in ascending specific order
find()
restore()
random()aren’t “randomizers” fun?

* and the “bare” bones - the preprocessed directives * What creates high level commands, and can replace or disable objects to emulate other programming languages at compilation time.
They can be grouped, and multiply defined when put in brackets.
They start with the pound or number character (#), and are also called “macros”.
(already existing)
define  or  substitute:   to name a label to that gets replaced with a certain text
undef  or  rid:   to delete a define’d label, if it exists
insert file, import, or include:   to add text of another file to the file in memory
pragma:   compiler specific settings
if, else, endif, elif, elseif:   conditionals
ifdef, ifndef:   “define” conditionals
(errors and warnings, usually used with conditional macros)
error:   gives an error at compilation time
obsolete, warning:   gives a warning at compilation time for whatever reason
(new)
concept:   the fundamental magic of this whole language
uses compiler-native op-codes to generate new format defined attributes and is really hectic if you don’t have much patience
plural:   defines the only plural name or a list of names for an identifier
Example: #plural mouse mice
-- “mouses” no longer works since it’s not in the list of new plural names

ignore  or  disable:  
disable a term or directive
revive  or  enable:   enable a previously disabled term or directive
numeric:   parameters for either a base number or a concept


preprocessed functions and constants

defined()
exists()
sizeof()
offset()
class()
__option()

__FILE__
__LINE__
__TIME__
__DATE__
__RESULT__

file


Index

Structures

size definition

Types

Strings

Values

Expressions

singular
dual
indirection

Other
temporary pointer

Bit Fields

Comment symbols

Loops

Identifier Sequences

Bit Enumeration

Previous Expression Comparison

Parameter Keywords

Special

command routines
format defined attributes
relative attributes
high level single array functions
preprocessed directives



DISCLAIMER

This programming language is based on C, and contains elements of other languages, such as Java, Pascal, HyperTalk, and Visual Basic.
I have no known connection to anybody that developed any programming languages, which includes the ones previously mentioned.
This text and any software generated for it is made out of will and convenience in the public domain. This comes without a warranty, copyright or patent, and is non-profit.  Neither I nor mentioned companies or entities are responsible for any actions, opinions, damage this file or related software may cause.
THE USER IS SOLELY RESPONSIBLE FOR DAMAGE CREATED BY USE OR MISUSE OF THIS FILE OR RELATED SOFTWARE.  USE AT YOUR OWN RISK.

HyperTalk is the language of HyperCard, a registered product and trademark of Apple Computer, Inc. ©1987-1998.
All other names may or may not be trademarks and/or registered trademarks of their respected owners.
All Rights Reserved.

Any legitimately offensive material may be taken out on request.

I’m trying not to go out of my league.

Created:Dec 22, 2003
Last Revised:March 31, 2010