O Language Documentation

I. Introduction

II. Declaring data

III. Basic operations

IV. Arithmetic operations

V. Bitwise operations

VI. Using pointers

VII. Using functions

VIII. Importing from libraries

IX. Using conditions

X. Looping

XI. Pointing on templates

XII. Including files

XIII. Creating executable files

XIV. Creating object files

XV. X File Syntax

XVI. Other operations

I. Introduction

The O language use constants, variables, pointers that are octal/decimal/hexadecimal numbers.
Elf object/executable files for Linux-based systems and Exe files for Windows and can be created. And C files with otoc.
Object files that have elf relocatable format can be created.
The language commands are case INsensitive.
At the beginning data can be declared with diverse methods.
The language has basic, arithmetic, bitwise operations.
The pointer mechanism is used to handle the variables more easily.
Functions can be declared and called.
External libraries can be imported.
Code conditions are if-elseif-else.
Files can be included to form complex programs.
There are 2 scopes: the global scope and the function scope.
The commands are from i386 with extension for x86-64 (but with the HEX macro anything can be wrote to code section).
4 bytes variables are sign extended to 8 by default(must add unsigned notation to zero extend). 1 byte variables are zero extended to 4/8 bytes when needed(otherwise must add signed notation). o[.exe] filename [options]
#key value options. more at configuration file.

II. Declaring data

The language has 7 names for data declaration (1 for constants and 6 for variables).

1. Constants
Language command: Const ConstIf
Is a 32 bit value. It's content is declared into the memory(variables are declared into the file) therefore it is used at header files.
Constants have a separate declaration scope.
Constants(like ordinary integers) can be used at operations, but to avoid same names these are introduced with parenthesis (); without parenthesis only one integer can be used
ConstIf will define the constant only if is not defined.
Example:
Const TRUE=1
if 20=(ConstantValue+11)
  set x 20
endif
Const x=3$2
#is 3 pow 2 = 9

2. Data
Language command: Data
Is a 32 bit value. It is used for operations, pointer operations.
Example:
Data variable=100

3. Strings
Language command: Str
Is a 32 bit value. It is used for pointer operations.
Example:
#for compatibility, on 64 reloc_64 pref is 1, if was 0 must use vstr mostly
Char chardata="Text"
Str string^chardata
Str text="Text data"

4. Characters
Language command: Char
Is a 8 bit value. It is used for operations.
Example:
Char value={1}
Char value=1
Char value="Add text here"

5 - 7. Stack variables
Language command: SD = Stack Data
Language command: SS = Stack String
Language command: SV = Stack Value
At 64bit code all stack variables are 8 bytes. 4 bytes at 32.
Stack Value differentiates at 64bit code. It will point at 8 bytes ('sv#'). At 32bit code sd and sv are the same. Sd is pointing at 4 and ss at 1.
These variables are located on the stack. The methods for declaring SD/SS/SV are the same as for Data/String.
Stack variables can be declared without a sign. The implicit method in this case is '#1' (reserve one unit).
Example:
Char chardata="Text"
function recursive(sd stackdata)
endfunction
ss string="Text"
sd reserve
sd another_reserve#1

8 - 10. Value variables
Language command: VDATA
Language command: VSTR
Language command: VALUE
They will declare 8 bytes for a unit on 64 bit format file.
The pointer is like for stack variables; vdata 4, vstr 1, value 4/8.

11 - 16. Virtual variables
Language command: DATAX
Language command: STRX
Language command: CHARX
Language command: VDATAX
Language command: VSTRX
Language command: VALUEX
These will be in a nobits section at object. Set nobits_virtual preference to 0 for old behavior: these will be physically placed after the counterparts and the starting offset will be logged so ostrip can remove them after ld linked the objects.

For otoc, adding U at the end, excepting constants, will make them unsigned in C, and excepting chars where adding S will make them signed.

Data can be declared using the following methods:

1. Equal sign ('=')

First method.
Example:
Const fruits=20
Data value=-70
Char text="The quick brown fox jumps over the laxy dog."
vStr stringASM=0x401000

Second method is with '{}' signs.
Example:
Data values={1,3,900}
Char bytes={1,4,100}
vStr pointers={0x401010,0x401020}

2. Reservation sign ('#')
Example:
Data reserveDATA#10
#the data section will have 40 bytes reserved
Char reserveCHAR#10
#the data section will have 10 bytes reserved
vStr reservePointers#10
#the data section will have 40 bytes reserved

3. Pointer sign ('^')
Right side can have variables and at object format, when left side is not constant, can have functions. Variables (value and sv) that point to a function can be called like a function. At the executables format (ex: not elfobj), when pointing to an import function the supported manner is with double pointer(^^); all cases, except this one, use the normal pointer(^).
Example:
Data value=1
Data pointervalue^value
Char bytes="Raw text data declaration."
vStr text^bytes

4. Relocation sign ('%')
Used at the object format. It acts like equal sign and then the offset is added to the REL section. At executables it translated to '='. At Str and quotations declaration the equal sign adds at object to Rel and this sign cannot be used here. At Char the sign cannot be used.
Add another '%' sign to point to .dtnb section instead of .data if applicable.
Example:
Format ElfObj
Data global=100
Const ptrglobal^global
Function test()
  Data local=200
  Data reference%ptrglobal
  Add local reference#
  #200+100
  Return local
EndFunction
Entry main()
  Data item#1
  SetCall item test()
  Data addmore=300
  Data apointer^addmore
  Add item apointer#
  #300+300
  Return item


Operations can be performed at declarations with arithmetic (+,-,*,/,//,%,%%,$), bitwise (&,|,^,~,<<,>>,>>>) and logical (=,!=,<,>,<=,>=,&&,||,<^,>^,<=^,>=^,!,!!) signs. - and ~ can prefix a number/constant.
Example:

const a=1
# add sub mul div divu rem remu pow and or xor notshl1 sar1 shr1 equalinequallessgreaterlessEqualgreaterEquallogicalAndlogicalOrunsignedLess unsignedGreaterunsignedLessEqualunsignedGreaterEqualparityodd neg
char *examples={3+2,6-4,5*5,32/10,-1//0x10000000,32%10,-1%%0x10,3$2,7&2,5|2,7^2,~0,2<<2,8>>3,-1>>>25,7=7, 7!=7, 2<3,2>3, 9<=9, 9>=9, 1&&0, 0||1, 1<^0xffFFffFF,1>^0xffFFffFF, -1<=^-2, -1>=^0, 4!1, 2!!1,-a}
#hex: 5 2 19 3 f 2 f 9 2 7 5 ff 8 1 7f 1 0 1 0 1 1 0 1 1 0 0 1 1 1 ff
const a=3*(1+2)
return (a) #9

If a variable is not used at code operations a warning will be displayed for that variable name. To create unreferenced values use the * sign.
Example:
Data struct=3
Data *structValue=1000
vData structures^struct
#the "structures" variable can be used in the program as a pointer
Entry event(data *widget,data signal)
return signal
#only the signal value is checked for unreferences

To disable the unreferenced warning or to set options at symbols see 'ocompiler.conf' file.

The data declarations can be made in the global scope or in the function scope. All the constants are in the global scope. When a function is declared all the variables declared in the function can not be used outside that function because they are in the function scope.
The "\" character represents the data section cursor and can be used in place of a number. "\\" represents the nobits data section cursor if applicable. "\function" will retrieve the data section size of that entry and "\\function" the virtual size. "\function\" will retrieve both. "\scope.variable" will get the size of the entity. "\scope.variable\" is the offset of the variable in the scope.
The ":" character represents the size of a long and can be used in the place of a number. Returns 4B on 32-bits, 8B on 64-bits.
"?" and a string is the value of the preference (example: ?x_file is x_file preference value).
The AfterCall set a value to be tested with zero at the every call and to return if it is not zero.
AfterCallImport is used in objects to import an extern defined AfterCall.
AfterCallEnable/AfterCallDisable automation commands (name is not used; if not imported, aftercall can be defined with unrefsign(*)).
& sign will create throwless variables.
function pre_test()
return 3
endfunction
aftercall interrupt
function test()
return 3
endfunction
entry main()
set interrupt 1
call pre_test()
#it is still going on
value &throwless^test
call throwless()
#it is still going on
call test()
#here is the end, the program last return was 3
return 5

III. Basic operations

1. Return
Language command: Return Ret Exit
The return command is used to terminate the program or a function.
The asm value termination is ret (0xc3). To return int 0x80(0xcd,0x80;linux sys_exit;eax=1,ebx=return value) use Exit.
To return without a value use Ret.
To return like Exit at main scope but using returns set exit_end preference to 1.
Example:
Data true=1
Return true
#the program exit code will be 1

2. Set
Language command: Set
The set command is used to set one value to another.
Example:
Data valueA=20
Data valueB=30
Set valueA valueB
#the valueA will be 30
sd string
set string "text test"
#string will point to "text test"

3. Base/Leave
Language command: Base Leave
Base is setting the Base Pointer and Leave is restoring the base pointer and is leaving.
Example:
format elfobj64
value z#1
function a()
leave main.z
end
entry main()
hex 144
base z
call a()
i3

IV. Arithmetic operations

1. Addition
Language command: Add
Example:
Data valueA=20
Data valueB=30
Add valueA valueB
#the valueA will be 50

2. Subtraction
Language command: Sub
Example:
Data valueA=20
Data valueB=30
Sub valueA valueB
#the valueA will be -10

3. Multiplication
Language command: Mult MultS
Example:
Data valueA=20
Data valueB=30
Mult valueA valueB
#the valueA will be 600
#imul at mults

4. Division
Language command: Div Rem DivU RemU
Example:
Data valueA=465
Data valueB=20
Div valueA valueB
#the valueA will be 23
Rem valueA valueB
#the valueA will be 3
#unsigned division (divu) and unsigned reminder (remu) is similar with constant operations presented at declaring data

5. Incrementation
Language command: Inc IncSt
The incrementation command adds one to the value.
Example:
Data value=30
Inc value
#the value will be 31
IncSt adds 4 bytes to the argument or 8 bytes when building for 64-bit application.
Example:
sd x#2;sd z^x
set z# 1;incst z;set z# 2
add z# x
#at z# will be 3

6. Decrementation
Language command: Dec DecSt
The decrementation command subtracts one from the value.
Example:
Data value=30
Dec value
#the value will be 29
DecSt subtracts 4 bytes from the argument or 8 bytes when building for 64-bit application.

7. Negation
Language command: Neg
Subtract the operand from 0.
Example:
Data value=30
Neg value
#the value will be -30

V. Bitwise operations

1. And
Example:
Data valueA=0x0101
Data valueB=0x0001
And valueA valueB
#the valueA will be 0x0001

2. Or
Example:
Data valueA=0x0101
Data valueB=0x0011
Or valueA valueB
#the valueA will be 0x0111

3. Xor
Example:
Data valueA=0x0101
Data valueB=0x0011
Xor valueA valueB
#the valueA will be 0x0110

4. Not
Example:
Data valueA=0x0f0F0f0F
Not valueA
#the valueA will be 0xF0f0F0f0

5. ShL1
Example:
sd shift_left_once=2
shl1 shift_left_once
#the value will be 4

6. ShR1 SaR1
Example:
sd shift_right_once=0x10
SHR1 shift_right_once
#the value will be 8
sd shift_right_signed_once=-2
SaR1 shift_right_signed_once
#the value will be -1

VI. Using pointers

Pointers can be used for manipulating the data. The pointer sign at code operations is '#'.
Example:

Data valueA=1
Data valueB=2
Data pointerA^valueA
Data pointerB^valueB
Add pointerA# pointerB#
#the valueA will be 3

Char data="ABC"
vStr string^data
Char c1#1
Set c1 string#
#the c1 will be A

Inc string
Set c2 string#
#the c2 will be B

function test()
data bits_per_sample=16
return #bits_per_sample
endfunction
#the function call will return the pointer, and the variable can be modified
sd a
setcall a test()
set a# 8

More can be done with the cast notations [the cast sign (^) is not mandatory]:
format elfobj64
sd a
ss b
hex 144;set a a#s^#cast data to string
Hex 144;set a a#v^#cast data to value
hEx 144;set b b#D^#cast string to data
heX 144;inc b#V^#and a one arg cast
Static variables can be used in all scopes: Format Elf
Data a=3
Function test()
  Data b=3
  Add b main.a
EndFunction
Entry main()
  Call test()
  Add a test.b
  Exit a ##9

VII. Using functions

Function can be declared and called later in the program. Functions must be closed with EndFunction(or End) command. To call a function use the Call command. To call a function and store the return value into a variable use the SetCall comand. The functions must be declared before the main scope. For example, at the first operation within the main scope (ex. basic Set command, or arithmetic Add command) the Entry Point is placed there and the Function statement it is no longer available.
The Entry command acts like a Function command but with some differences: 1. the scope is not changed to a local scope; 2. the function is not added to the unreferences list; 3. the endfunction command is not used at this function.
EntryRaw is an Entry command which is acting like it does not have a value for Ret at the top of the stack and without a calling convention.
FunctionX is described at objects. FunctionXV and EntryV will handle the input arguments as if they don't know how many there are (varargs). Varargs are also at other function definitions for otoc.
All functions can be used in combinations like AddCall, OrCall, XorCall, etc (set a b() is same as setcall a b()).
CallEx is for prepared calls. This is a 3 argument operation. The first argument is the function name, the second argument is the arguments pointer and the third argument is the number of arguments. The arguments are passed forward respecting the size of the integer(4 bytes on 32-bits app, 8 on 64). One usage can be when there is a call with a number of arguments detected at run-time and want to pass them all to another call.
CallX, ...XCall, CallExX will call like a FunctionX/ImportX.
Call[X]G, ...[X]G, CallEx[X]G will skip aftercall.
Call[Ex][X]Ret can return from a function. Note that "G" is useless when "RET" is coming.

Example:

Function numbers_inter(Data a)
  sd value
  setcall value numbers(a)
  return value
EndFunction
Function numbers(Data a)
  Data addmore=10
  Data outvalue#1
  Set outvalue a
  Add outvalue addmore
  Return outvalue
EndFunction
Data value=20
Call numbers(value)
#the return will be 30

SetCall value numbers_inter(value)
#the value will store 30

char format="%i %i"
sd args^format;sd *={100,200}
CallEx printf #args 3

VIII. Importing from libraries

The functions can be imported from an extern library and used like in the previous chapter. To declare a library use the Library and to import a function use the Import command and provide the program function name.

Example:
#A Hello World program
#the default format is Format Exe
Library "user32.dll"
Import "MessageBoxA" Message 4v #4v is used by otoc, 4 arguments, and V/v varargs if present
Char program="Program"
vStr title^program
Char data="Hello World"
vStr text^data
Data null=0
Call Message(null,text,title,null)
#a message will be displayed with the "Hello World" text and the title "Program"
Return null

IX. Using conditions

The language has if-elseif-else conditions that must by closed with endif-endelseif-endelse(or end) commands. The condition operators are:
Equal: =
Not Equal: !=
Less: <
Greater: >
Less or Equal: <=
Greater or Equal:>=
Unsigned Less: <^
Unsigned Greater: >^
Unsigned Less or Equal: <=^
Unsigned Greater or Equal:>=^
Parity: !
Not Parity: !!

Example:

Data a=3
Data b=10
Data c#1

If a>=b
  Set c a
  #This will not be executed
ElseIf a=b
  Set c a
  #This will not be executed
Else
  Set c a
  #This will be executed
EndElse

If a<b
  Set c a
  #This will be executed
EndIf

If a>b
  Set c a
  #This will not be executed
ElseIf a<=b
  Set c a
  #This will be executed
EndElseIf
#More examples at the source code tests

X. Looping

sd a=5
sd b=0
while b<a ##whiletrue is without a condition
  inc b
  if b=1
   continue
  endif
  break
endwhile #or end

XI. Pointing with templates

Can point at compile time structures or at runtime structures with ':' sign.   format elf
  entry main()
  sd a
  sd b=3
  sd c^a
  sd d
  set d c#:b
  add d a:b
  exit d ##3+3

XII. Including files

The program can be formed with multiple files using the Include command.
If wanting to switch between two files (one use can be at multiple OSes) add a second path at the command: the preference include_sec 0 will take the first path, 1 will take the second path.
EInclude will turn unreferenced warning off (one use can be when including a header between multiple projects).

Example:
Include "files\\headers.oh"
Include "files\\headers_win.oh" "files\\headers_lin.oh"
eInclude "/usr/include/ocompiler/logs.oh"

XIII. Creating executable files

Exe files for windows will be created by default. Executable and Linking Format (ELF) files can be created for Unix - System V, operable on linux platforms. format elf will override the default format exe.

Example:
#linux example
Format Elf
Library "libc.so.6"
#at first library, the interpretor is created: "lib/ld-linux.so.2"
Import "printf" printf
char newlinedata={0xa,0}
vstr newline^newlinedata
call printf(newline)
char hello="Hello World!"
vstr helloworld^hello
call printf(helloworld)
call printf(newline)
data one=1;return one
#linux sys_exit with the argument 1

XIV. Creating object files

Object files can be created that have elf relocatable format. The format is ElfObj. The relocations are created automatically. There is the possibility to use the relocation sign ('%') when declaring a data that acts like equal sign but it also creates a relocation symbol to that address.

Example:
Format ElfObj
Data value#1
Data pointervalue^value
Entry main(data argc,data argv)
Set value argc
Data example#1
Set example argv
Return pointervalue#

64-bit objects with 64-bit stack data and Microsoft/Linux calling convention can be created by adding 64 at Format ElfObj.
To mark a function for 64-bit convention convention import with ImportX or declare with FunctionX. FunctionX is also treated as an extern function that can be called from another program (no log for ounused and no warn).

Example:
Format ElfObj64
Entry main(data *argc,data *argv)
importx "printf" printf
if :!=8
call printf("Not at 64 bits")
return 1
endif
sd returnvalue
setcall returnvalue printf("Test: ")
call printf("long %lx",returnvalue)
Return 0

64-bit can be ignored from preferences. Cross-compiles can be made at the same option from preferences.

Append SO at format to inform the log parser (ounused) to skip input/output functions and constants. This is a debugging option.
Example: Format elfobj64so

XV. X Syntax

Black = 1 byte. Blue = 4 bytes = data. Red = string = data[+byte(s)]. Green = replacement.

There are at least two options at the '*' wildcard from there. '{}' is an enumeration.

First long(4 bytes) is null or offset of entry which will be at the end.

Xfile_noignore at ocompiler is '^' sign before the command, and at otoc will noignore a tagIgnore argument. Xfile_yesignore at compiler is '!' sign before the command and at otoc will ignore the command. Xfile_variadic at ocompiler is '%' sign at start, followed by '<argument' for va_start at otoc, '&variable' for va_copy, '|variable' for va_arg, '>' for va_end. va_copy will also replace 'the_va_list' with variable until va_end.

Another option specific to otoc is Xfile_c_volatile, to use stack variables at o for recursion but not pointers at c (example: sdu ?attr). And Xfile_c_variadic to work with va_list arguments.

Xfile_protoXfile_function_t_*namenr_of_args{DA}Xfile_proto_*
Xfile_importXfile_import_*SinternXfile_function_va_*nr_of_args
Xfile_comment*comment
Xfile_formatXfile_format_*
Xfile_includeXfile_include_normal
Xfile_include_extern
SXfile_include_alternative_no
Xfile_include_alternative_yes S
Xfile_functiondefXfile_function_t*Xfile_function_va_*nameXfile_function_t_*nr_of_args{D}
Xfile_function_e*
Xfile_declareDXfile_declsign_pointer Xfile_declsign_pointer_*var/fn
Xfile_declsign_reserve N
Xfile_declsign_e*Xfile_declmode_value N
Xfile_declmode_group nr_of_args{N}
Xfile_declmode_string S Xfile_declmode_string_pop_*
Xfile_actionXfile_action_a*A
Xfile_action_t*VF
Xfile_action2VFXfile_action2_*A
Xfile_call Xfile_call_*CL
Xfile_callex CVFA
Xfile_if CD
Xfile_elseif CD
Xfile_else
Xfile_while CD
Xfile_whiletrue
Xfile_break
Xfile_continue
Xfile_endXfile_end_*
Xfile_ret
Xfile_libraryS
Xfile_import_namename
Xfile_aftercallXfile_aftercall_declareXfile_declfeature_normal
Xfile_declfeature_unref
var
Xfile_aftercall_import var
Xfile_aftercall_enable
Xfile_aftercall_disable
Xfile_hexnr_of_args{N}
Xfile_overridenameN
Xfile_orphanXfile_orphan_*
Xfile_interrupt
Xfile_line
Xfile_iend
Xfile_variadicXfile_variadic_begin var
Xfile_variadic_copy
Xfile_variadic_get
Xfile_variadic_end
Xfile_noignore
Xfile_yesignore

Table A:
Xfile_arg_numberN
Xfile_arg_stringS
Xfile_arg_varfn VF
Xfile_arg_call CL

Table C:
Xfile_arg_call_*var/fn

Table CL:
Cnr_of_args{A}

Table CD:
AXfile_cond_*A

Table D:
Xfile_declfield_constXfile_declfield_const_*name
DA Xfile_declfeature_*

Table DA:
Xfile_declfield_stack Xfile_declext_*Xfile_decltype_*Xfile_c_*
Xfile_declfield_data Xfile_declfield_data_*
Xfile_declfield_varargs

Table DT:
funcfV

Table N:
[Xfile_numbers_parenthesis_open]Xfile_numbers_prefix_*Xfile_numbers_type_i* [Xfile_numbers_parenthesis_close][Xfile_numbers_operation_*]{...}Xfile_numbers_done
Xfile_numbers_type_t*text
Xfile_numbers_type_f*funcf
Xfile_numbers_type_v*DT

Table S:
Xfile_string_multiline_*string

Table V:
var/fnXfile_suffix_false
Xfile_suffix_true Xfile_suffix_cast_*
Xfile_suffix_notasuffix

Table VF:
Xfile_arg_varfn_prefix_*Xfile_arg_varfn_colon_no
Xfile_arg_varfn_dot_no V
Xfile_arg_varfn_dot_yesDT
Xfile_arg_varfn_colon_yesXfile_arg_varfn_dot_no varXfile_suffix_*
Xfile_arg_varfn_dot_yes funcf

Arg Call CaLl ConD Decl DeclArg DoT f Nr S Var VarFunc

XVI. Other operations

Other commands that comes with the language.
1. Comments
To comment the code use the sign # before any text.
Multiline comments are using #! ... ! syntax.  format elf
  sd a=2; #! 1111
  2222
  3333
  ! ; inc a
  exit a ##will be 3

2. Interrupts
To place software breakpoints use the I3 command.
3. Hex
Write bytes in the code section.
4. Orphan
Turn on or off the orphan warnings.
5. Override
Override preference. Note that preference order is default < preference_file < command_line_argument < override.

Example:
#This is a comment and it will not be executed
I3 #a line ending comment
sd a;set a a ##line ending comment (with two), only one #, in this case, is a pointer
#this will pause the program into a debugger
HEX 0x33,0xc0,0xC3
#this will write 3 bytes in the code section
orphan off
import "common_function" common
orphan on
#useful when having a header in multiple objects
override underscore_pref 0
importx "__errno_location" errno
#if uderscore_pref is 1 the symbol is _errno_location, that can be wrong

When the option function_name from the ocompiler.conf file is set to Yes(1), the name is wrote in the code section above the function, for debugging asm code.
The preferences file can be placed in HOME folder on linux.
Lines are ended with new line(0xa),carriage return and new line(0xd,0xa) or semicolon(0x3B).
The command line options are detailed at some point on the linux console std. On windows there some dialogs instead of console std.
has_debug option will add a .debug section at objects that acts like the log file for files hierarchy and another log, log_line, A,B format, where A is the line number and B is the code section offset where it starts. To see the content, for example, run
 objcopy -O binary --only-section=.debug --set-section-flags .debug=alloc file.o file.txt