0. Introduction
1. Declaring database
2. Creating table relations
3. Printing database contents
4. Selecting class elements
5. Navigation through the relations
6. Updating data
7. Set variable
8. Table manipulation, exporting and importing
9. Limitation in class names and values
10. Meaning and quoting
11. Program objects
12. Multilevel classification
A. Language Reference
Constructions 1
$base S = ; Opens modifiable database with S name. S may be enclosed in "..." or in '...'.$base S != ; Opens S database as new modifiable. Old
database is deleted.
= $base S ; Opens S database as non-modifiable (only readable).
$base S ; Sets S database as current. If database was not opened yet, opens it as modifiable.Examples 1
See the following test example. The --..., (: ... :) constructions are Smans comments. The A='a' Smans description creates new A 'a' element in notedb/temp.sdb database. The =A is a Smans request, which prints values of A elements.-- 1.1. Testing database declaration
-- Declares 'temp' database as modifiable
$base "notedb/temp" =;
A = 'a';
-- Current 'temp' database will be only for reading
= $base;
= A;
-- Declares 'other' database, modifiable by default
$base "notedb/other";
= A; -- A is non-existent in 'other' database
-- Back to 'temp' database non-modifiable due to previous declaration
$base "notedb/temp";
= A;
-- Clears database
$base != ;
= A;
(: -- Test non-modifiable database
= $base;
A =;
:)
Constructions 2
readTable() (:Smans does not assume the type declaration. Example above demonstrates all the possible value types, R column contains # identifiers, A contains '...' single quoted strings, and B column contains numbers. The "..." string is not value in Smans. Double quoted string is useful to express a complex column name with special symbols and blanks. More about data types and their limitations see 9.Limitation... section. While, there is no schema control in Smans. It is similar to XML for which DDT or XML schema is eligible but optional.rt() (:
R; A; B
#1; 'a1'; 1
#a; '()'; 2.9
:)
rt() (:
R; A; B
#1; 'a1'; 1
#1; 'a1'; 2
:)
Following constructions explains addition the new rows and fields to R table. If table does not exist yet, it will be created.rt() (:
R; A; B
#1; 'a1'; 1, 2
:)
D = ; It is general definition of Smans statement, which is
used to add new data in a database. The D expression in this case is a
description. Below are some detailed elaborations of D description used to add a new row
or fields
in the R table.
R #[A 'a', ...] = ; Adds new row with fields R #, A 'a',..., where R # is primary key field. Because # identifier is indefinite, system automatically generates new. We can suggest that the R[A,...] is a relation header (or schema without type definition) in terms of relational model. In this case the R #1[A 'a', ...] will be tuple <#1, 'a', ...>. Inside of description it is possible to separate name and value of the field (data element) by means of colon ':', like R:#1[A:'a', ...].
R 'r'[A 'a', ...] = ; Adds R 'r', A 'a',... fields to the R table. Here R 'r' is a primary key field. In case if R 'r' row exists the A 'a',... will be added to that row. Remind that value type may be other.
R[A 'a', ...] [B 'b', ...] = ; Here A 'a',... fields in first brackets are considered as key (beside R). If R table already has rows with A 'a',... key, this statement adds new B 'b',... fields to that existent rows. Otherwise, new row R #,A 'a',...,B 'b',.... will be added.Examples 2
Now input the table information.readTable() (:Result is this table:
note; fellow; telephone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#; 'Smith Anne'; '400 297-0752'; '10 Seventh Av'
:);
note fellow telephone addressFollowing statement adds new #4 row with the multiple valued field telephone.
#2 'Forman Daniel' '650 756-9546' '27 Crestline Ave'
#3 'Smith Anne' '400 297-0752' '10 Seventh Av'
note #[fellow 'Ringer Michael',
telephone {'415 506-0111', '503 743-5226'},
address '4 Broadway Av'] =;
The statement below will not add a new row, because the note[telephone '400 297-0752'] exists already in #3 row.
note [telephone '400 297-0752'][Look at the resulted table with the multiple valued fields.
fellow 'Smith Robert',
address '10 Seventh Av'] =;
note fellow telephone address
#2 'Forman Daniel' '650 756-9546' '27 Crestline Ave'
#3 'Smith Anne' '400 297-0752' '10 Seventh Av'
'Smith Robert'
#4 'Ringer Michael' '415 506-0111' '4 Broadway Av'
'503 743-5226'
Constructions 3
printSchema() ; Prints schema of the current database. Schema is generated as a set of expressions, like R[A,B].The $file "F" parameter may be missing in all these procedures. In this case, system
prints
output in the Report area
(window
or API buffer). If Q queries
are
missing, procedures print all the
possible tables,
relations, classes and so on. The print()
without E parameters prints
empty line. Smans enables abbreviations pt, ptr, pr, pc, ps, pth, p
for correspondent procedures printTable, printTableRows,
printRelation, printClass, printSchema, printTableHead,
print.
Examples 3
Try to print all the "schema relations" from 2. Creating....print("--- DB
SCHEMA ---");
printSchema();
Result will be such:
--- DB SCHEMA ---Before printing the note table there is sense in counting number of its rows. Sometimes, printing of table head may be useful also. Below and further all the Smans fragments are separated from printed result by "-----" line.
note[
address,
fellow,
telephone
];
print("Total notes: ", count(note));
printTableHead(note);
-----
Total notes: 3
note; fellow; telephone; address
Now, it's time to print table at last.
printTable(note);The above is a usual view of printed table. Values inside field are separated by ',' comma, fields are divided by ';' and each row is located in a single line. To print table in external file printTable should have $file parameter.
-----
note; fellow; telephone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#3; 'Smith Anne', 'Smith Robert'; '400 297-0752'; '10 Seventh Av'
#4; 'Ringer Michael'; '415 506-0111', '503 743-5226'; '4 Broadway Av'
printTable($file "notedb/notes0.tab", note);Let's see example of projection note table to fellow and telephone columns.
printTable(note, fellow, telephone);Below is example of other Smans procedures. Notice, to print only values of fellow class, the '=' is used with =fellow query.
-----
fellow; telephone
'Forman Daniel'; '650 756-9546'
'Smith Anne', 'Smith Robert'; '400 297-0752'
'Ringer Michael'; '415 506-0111', '503 743-5226'
printRelation(first(note));Actually, to print concatenation of the some words with query result, the string like below seems more advanced. Here we print only fellows related with notes.
printClass(fellow);
print("All fellows: ", =fellow);
-----
note #2[address '27 Crestline Ave',
fellow 'Forman Daniel',
telephone '650 756-9546'];
fellow {
'Forman Daniel',
'Ringer Michael',
'Smith Anne',
'Smith Robert'
};
All fellows: {'Forman Daniel', 'Ringer Michael', 'Smith Anne', 'Smith Robert'}
"Note`s fellows: {=fellow[note]}";
-----
Note's fellows: {'Forman Daniel', 'Ringer Michael', 'Smith Anne', 'Smith Robert'}
Constructions 4
Q ; The Q denotes
query expressed in Smans language. Goal of any query is to defined
value
of class existent in database. For example, statement consisting of
class name or their composition
with each other is a query, if those names are present without
correspondent values. The A 'a'
expression says about 'a'
value of A class and it is
not query. In
this case,
query should be enclosed as ?{A 'a'} or
looks like {A='a'}
or A{.='a'}.
Expression is a query if includes some indefinite symbols, for example
such
as '%' - any term (name or value), '*' - any name, '.' - any value.
The '%' is used
independently or with symbol sequence in name or value. For example,
'%man%'
reflects value as indefinite
string with man sequence. It
is useful to remember that '%'
denotes any string value, #%
- any identifier, and 0% -
any number. Below there are more detail query constructions.
=Q ; This expression
reflects
only value, no class names.
Q[Q1 |/&/, ...] ; Selects elements of Q classes having relation with Q1 classes or/and/, so on. The '|', '&', and ',' inside of [] executes predicative logic with possible comparison. The ',' has the same meaning as '&' inside of []. To make the set operation, we need to use braces inside of brackets, like Q[{Q1&Q2}]. The definition includes following, more detail.
Q[Q1 =/>/</>=/<=/!= E |/&/, ...] ; Selects elements of Q classes having relation with Q1 classes, which values are defined by E expression (equal/more/...) and so on. Simple example in XPath style may be such: A[A1 >= 'a1']. It is adequate to the RESTRICTION of the relational algebra: A WHERE A1>= 'a1'. In Smans, on place of any Q or Q1 query a complex expression is supposed, not only simple class (or column) name, like A. On place of E expression a query or values of some type are implied.
Examples:
A[B={#1,'a', 23.9}] ; Considers B equal to one of the three possible values.
{A,B}[{C,D}>1] ; Selects A and B related with C or D.
A[D[E='%er']] ; Here E equals to any string value ended with 'er'.
A[B>C,D] ; The all B values are more then maximal value of C.
Q[. =/>/</>=/<=/!= E |/&/, ...]
;
{Q =/>/</>=/<=/!= E
|/&/, ...} ;
Q{. =/>/</>=/<=/!= E |/&/, ...} ;
Q{ =/>/</>=/<=/!= E |/&/, ...} ; All these
constructions are equal and select elements of Q classes, which values are defined
by E expressions and so on.
On place of E expression a
query or values of
any type are
implied. First construction is inherited from XPath. Nevertheless,
semantically more preferable to enclose the values inside of {}, and
relation inside of [].
Examples:Q{E1 - E2} ; or Q{E1 to E2} ; Queries express a range of values.
*{.!=C}[B] ; Selects elements having values different to C (values of C) and related with B class.
A{=#%} ; Selects A elements with any identifier (#%).
A{>0 & <6} ; Selects A elements more than 0 and less than 6.
A%{1 - 5} ; Selects A... elements with values between 1 and 5.
Example:All the complete expressions (statements) are separated by the ';'. If statement ends with '=', like D =, the operand D is a description, not query (or request). See A.Reference... about all the Smans operators, ordered from highest to lowest precedence. Consecution of operators is executed from left to the right.
A%{1 - 5} ; Selects A... elements with values between 1 and 5.
Examples 4
Return back at the previous 3 example. We consider some notes in the note table. Remember that many examples in each next division further are the continuation of examples from the previous divisions, in this document.| note |
fellow | telephone | address |
| #2 |
'Forman Daniel' | '650 756-9546' | '27 Crestline Ave' |
| #3 |
'Smith Anne', 'Smith Robert' | '400 297-0752' | '10 Seventh Av' |
| #4 |
'Ringer Michael' | '415 506-0111', '503 743-5226' | '4 Broadway Av' |
telephone[note];Result in the Report area:
telephone {
'400 297-0752',
'415 506-0111',
'503 743-5226',
'650 756-9546'
};
Let's image telephones
related with notes #3 or #4. Beside the following fragment, telephone[note{.={#3,#4}}]
has the same meaning.telephone[note = #3 | note = #4];
-----To print all the notes having definite relation it is possible to use note[*], but it will run slower than simple note query getting all the elements of note class.
telephone {
'400 297-0752',
'415 506-0111',
'503 743-5226'
};
note[*];
-----Following fragment prints two statements about note classes having relation with fellow 'Ringer Michael' and having relation with other.
note {
#2,
#3,
#4
};
note[fellow = 'Ringer Michael'];
note[fellow != 'Ringer Michael'];
-----If we want to print correspondent notes and telephones with code less than 416, following statements may be helpful.
note #4;
note {
#2,
#3
};
telephone{. < '416'};
note[telephone < '416'];
-----To telephone feature of example above let's add fellow. Statement may have view note[telephone<'416'&fellow='Ringer Michael'] or as below.
telephone {
'400 297-0752',
'415 506-0111'
};
note {
#3,
#4
};
note[telephone < '416'][fellow = 'Ringer Michael'];
-----Following are expressions printing telephones with area code in range between 100 and 415. The 416 will not be printed in any case if numbers are longer than 3 digits ('416' < '416 000-0000').
note #4;
telephone{. = ('100' to '416')};
note[telephone{. = ('100' to '416')}];
-----Now examples of the set theory are suggested.
telephone {
'400 297-0752',
'415 506-0111'
};
note {
#3,
#4
};
note[*] except note[fellow = 'Ringer Michael'];
"--";
note[*] intersect note[fellow = 'Ringer Michael'];
"--";
note[*] union note[fellow = 'Ringer Michael'];
-----Finally let's output all the notes that have relation with 'Ringer...'.
note {
#2,
#3
};
--
note #4;
--
note {
#2,
#3,
#4
};
note[* = 'Ringer%'];
-----
note #4;
Constructions 5
Examples 5
We have table existent already in database:| note |
fellow | telephone | address |
| #2 |
'Forman Daniel' | '650 756-9546' | '27 Crestline Ave' |
| #3 |
'Smith Anne' 'Smith Robert' |
'400 297-0752' | '10 Seventh Av' |
| #4 |
'Ringer Michael' | '415 506-0111' '503 743-5226' |
'4 Broadway Av' |
| fellow | birthday | profession |
| 'Forman Daniel' | ||
| 'Mann Arthur' | '1979/04/04' | 'developer' |
| 'Ringer Michael' | '1973/05/20' | 'database admin' |
| 'Smith Anne' | '1981/02/13' | 'Web designer' |
| 'Smith Robert' | '1982/12/01' | 'group manager' |
note/;Following statements print fellow elements related and non-related with note class.
-----
address {
'10 Seventh Av',
'27 Crestline Ave',
'4 Broadway Av'
},
fellow {
'Forman Daniel',
'Ringer Michael',
'Smith Anne',
'Smith Robert'
},
telephone {
'400 297-0752',
'415 506-0111',
'503 743-5226',
'650 756-9546'
};
note/fellow;Database has two fellow 'Smith%' elements. To get all telephones related with their, there are few possible statements, for example fellow{.='Smith%'}/note/telephone or telephone[note/fellow{.='Smith%'}]. Below is other '//' statement.
fellow ! note/fellow;
-----
fellow {
'Forman Daniel',
'Ringer Michael',
'Smith Anne',
'Smith Robert'
};
fellow 'Mann Arthur';
fellow{. = 'Smith%'}//telephone;
-----
telephone '400 297-0752';
To find fellows of profession including words 'Web' or 'developer' we can use statement fellow[profession{.={'%Web%','%developer%'}}].
Below, slightly simpler expression is presented and it is used as a
step of '/' path expression.
birthday{. > '1975'}/fellow[profession{'%Web%', '%developer%'}];
-----
fellow {
'Mann Arthur',
'Smith Anne'
};
Constructions 6
Examples:A1 == A0 ; Changes name of a class from existent A0 to a new, A1. Remind that Smans database is a class-relational. Changing of A0 class means changing of A0 relation that A0 class represents.
month = {1,2,3,4,5,6,7,8,9,10,11,12};
vacation #[month = 13] =; This description will not be executed, because {month = 13} is not existent.
Examples:
A #1[B] !=; Before to set a new A[B] relation for A #1, this statement deletes old existent.
{A=#1}[B>'b'] =; Sets A[B] relation for existent A #1 with B elements that have value more than 'b'.
?{A#}[B#] =; Sets A[B] relation between existent last A# element and new B# element.
Examples 6
Go back to the previous Example 5. We need to set new phone class name in place of old telephone. Beside this, 415 506-0111 telephone number should be changed.phone == telephone;Suppose that Smith couple is separated and we place Smith Anne in other note record.
phone '415 506-0999' == phone '415 506-0111';
note[fellow 'Smith Anne'] !=;Now we set a phone element to the last note.
note #[fellow 'Smith Anne'] =;
?{note #}[phone '511 666-3344'] =;
Anne has still the same
address as Robert, only phone
is other 511 666-03344.-----Just in case save notes from #4 to #10 in a new note2008 table. First statement below creates note2008 class which values coincident with existent notes in range from #4 to #10.
-- ISSUE DATABASE --
fellow; birthday; profession
'Forman Daniel'; ;
'Ringer Michael'; '1973/05/20'; 'database admin'
'Smith Anne'; '1981/02/13'; 'Web designer'
note; fellow; phone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#4; 'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
#5; 'Smith Anne'; '511 666-3344'; '10 Seventh Av'
-----
-- NEW TABLE --
note2008; fellow; phone; address
#4; 'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
#5; 'Smith Anne'; '511 666-3344'; '10 Seventh Av'
Constructions 7
Examples 7
Let's print the current note table and then $note variable containing notes related with Ringer.printTable(note);Now in place of note #4 (or something more complex) we can use $note variable in a query.
$note := note[* = 'Ringer%'];
$note;
-----
note; fellow; phone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#4; 'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
#5; 'Smith Anne'; '511 666-3344'; '10 Seventh Av'
note #4;
fellow[$note];Variable may be used not only to keep elements, but also class names and values. Below the $phone variable keeps phone that is a class name used in the following queries. The $x variable gets some values of phone class existent in database.
-----
fellow 'Ringer Michael';
$phone := %ph%;Following fragment prints $phone and $x variables in a string context.
$x = {$phone != '415%'};
"$phone := {$phone};";
"$x = {$x};";
-----
phone := {phone {'415 506-0999', '503 743-5226', '511 666-3344', '650 756-9546'}, work_phone '503 743-5226'};
$x = {'503 743-5226', '511 666-3344', '650 756-9546'};
Constructions 8
readTable($file "F", N0, N1, ...) ; Reads table from F file with column numbers N0 key, N1, .... The contraction, rt(...), is able. If F file parameter is missing, imported tabular data are located immediately after procedure expression, in (: :) brackets. See 2. Creating table relations. If there are not N0, N1, ..., all the columns will be input.Notice large profit of readTable() and printTable()
procedures for database
archiving. The
F
file may be directory, without extension ( .tab). For example,
if
database consists of R1, R2 tables, printTable($file
"tables")
exports
all the tables in tables/R1.tab and tables/R2.tab
accordingly.
Then we can import all the files from tables directory by readTable($file
"tables").
addColumn(table, column0, column1) ; Adds column1
after column0 in
the table. The ac() is abbreviation. This
procedure
helps not only to add new column, but also change column order if
column1 exists already. Only
first key column in the table remains invariable.
Examples 8
First of all let's print the current database we formed in the previous examples. Database keeps schema of 3 tables fellow[birthday, profession], note[fellow, phone, address], note2008[fellow, phone, address].pt();We are interested in a join of the first two tables, note and fellow. See below fellow projection of that joined table.
-----
fellow; birthday; profession
'Forman Daniel'; ;
'Ringer Michael'; '1973/05/20'; 'database admin'
'Smith Anne'; '1981/02/13'; 'Web designer'
note; fellow; phone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#4; 'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
#5; 'Smith Anne'; '511 666-3344'; '10 Seventh Av'
note2008; fellow; phone; address
#2; 'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'
#4; 'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
#5; 'Smith Anne'; '511 666-3344'; '10 Seventh Av'
pt(note, fellow, address, phone, fellow.birthday, fellow.profession);To connect directly fellow with address and phone, in other words to form table fellow[address, phone, birthday, profession], we can print aforesaid table in external file through the pt($file"fellow.tab",<the same parameters>) and then read it rt($file "fellow.tab").
-----
fellow; address; phone; birthday; profession
'Forman Daniel'; '27 Crestline Ave'; '650 756-9546'; ;
'Ringer Michael'; '4 Broadway Av'; '415 506-0999', '503 743-5226'; '1973/05/20'; 'database admin'
'Smith Anne'; '10 Seventh Av'; '511 666-3344'; '1981/02/13'; 'Web designer'
pt($file "notedb/store1/note.tab", note);Let's rename profession column to profile and change heading order to fellow;phone;address;birthday;profile.
rt($file "notedb/store1/note.tab", 2, 3, 4);
note% !=;
pt();
-----
fellow; birthday; profession; phone; address
'Forman Daniel'; ; ; '650 756-9546'; '27 Crestline Ave'
'Ringer Michael'; '1973/05/20'; 'database admin'; '415 506-0999', '503 743-5226'; '4 Broadway Av'
'Smith Anne'; '1981/02/13'; 'Web designer'; '511 666-3344'; '10 Seventh Av'
profile == profession;
ac(fellow, fellow, phone);
ac(fellow, phone, address);
pt();
-----
fellow; phone; address; birthday; profile
'Forman Daniel'; '650 756-9546'; '27 Crestline Ave'; ;
'Ringer Michael'; '415 506-0999', '503 743-5226'; '4 Broadway Av'; '1973/05/20'; 'database admin'
'Smith Anne'; '511 666-3344'; '10 Seventh Av'; '1981/02/13'; 'Web designer'
Constructions 9
There are following types of class value possible in Smans language:
N - integer number. The maximal
value is 2147483647 (for non-commercial version);
N.N - fractional number. The
maximal value is 2147483647.999999. Digits (at least 0) must be
before
point. Maximal number of digits after point is 6;
'...' - single quoted string.
Inside of ' quotes may be any symbol except the same ' single quote;
#S - identifier. Any symbol may be in
S sequence except special
$'#\"*%({[)}] :`/=<>!&|?,; The '.' and '-' may be used
as joining symbols.
Possible simple class names are represented in the following view:
A - usual simple name. Such
name begins
with letter and contains any symbol except special (as #S). The '.' and
'-' are used as joining symbols;
"..." - double quoted
name.
Any symbol, except ", may be inside of "..." quotes. The "..." is
useful
if name includes special symbols including blank.
@S - At-name. The same rule as
for #S is acceptable for
possible S symbols.
Maximal length of name or value is 252 symbols (for non-commercial
version). If number
does not conform to specified criteria, it is taken to be non-numerical
value. Numerical values may be useful for correct order of output
data. It regards to identifier also, that is #9 < #10, whereas a10 < a9, '10' < '9'.
There is limitation for relations including attributes with "..." or @S names. For example A 1[B 2]= statements, beside A[B] relation, forms in database classes A and B. Elements of such classes are accessible independently. For example, B query gives B 2 element. In case of A 1[@B 2]= or A 1["B" 2]= , @B or "B" elements are not independent and are accessible only through the A key class, for example by queries A/@B or @B[A].
Examples 9
These examples show some exceptional situations the user should foresee working with specific names and values. The pr() procedure below, that is printRelation(), prints all the relations formed in notedb/temp database by only one statement office 'billing' [employer 0100, @comment 'unknown', "basic support" 'billing'] = . As result two classes, employer and office, are accessible directly, no more.$base "notedb/temp" !=;
"-- office RELATION --";
office 'billing' [employer 0100,
@comment 'unknown',
"basic support" 'billing'] =;
pr();
-----
-- office RELATION --
employer[] 100[office 'billing'],
office[] 'billing'[@comment 'unknown',
"basic support" 'billing',
employer 100];
"-- office CHECKING --";Let's create "basic support" as key independent class. It is possible. Before it was attribute class dependent on employer key class. The office class is not needed more and we delete in the first statement.
"AVAILABLE CLASSES";
*;
"CLASSES RELATED WITH @comment";
*[@comment];
[employer]; -- works
[@comment]; -- does not work
*[@%]; -- does not work
-----
-- office CHECKING --
AVAILABLE CLASSES
employer 100,
office 'billing';
CLASSES RELATED WITH @comment
office 'billing';
office 'billing';
;
;
'-- "support" RELATION --';The "..." simple statement is used to print string's content. Following are example of queries where "..." is a class name.
office !=;
"basic support" 'billing'[employer 0100,
@comment 'unknown'] =;
pr();
-----
-- "support" RELATION --
"basic support"[] 'billing'[@comment 'unknown',
employer 100],
employer[] 100["basic support" 'billing'];
'-- "support" CHECKING --';Last example demonstrates ordering of values, which is automatic in Smans. First statement makes non-suitable very long numbers. System takes their but orders as sign sequences, not numbers. So, they are placed last in the printed sequence.
"basic support" .;
{"basic support", "any"};
-----
-- "support" CHECKING --
"basic support" 'billing';
"basic support" 'billing';
"-- ORDERING --";
employer {121474836470, 1111111111111111111111111111} =;
employer 2147483647.999999 =;
employer {#100, '100', 100} =;
employer;
-----
-- ORDERING --
employer {
100,
2147483647.999999,
'100',
#100,
1111111111111111111111111111,
121474836470
};
Constructions 10
quote(E, S) ; Quotes E
as S-quoted string. The optional S may
be double that denotes "..." strings as result. To produce
'...' strings, S
may be missing or be single. Contraction of quote() is q().
unquote(E, S) ; Unquotes E from S-quoted string. The optional S may be double or single, but usually is not used. In last case, unquoting is automatic. Contraction of unquote() is $uq().
Examples 10
After R[A
#, B #][]= statement the database will
contain
relation like R #1[A #1,B #1]. Then we create query
'A[R]'[subject 'A']= relation to show how Smans query may
be saved and got.
R[A #, B #][] =;
query 'A[R]'[subject 'A'] =;
p("Meaning of query=", =query);
meaning(=query);
$xq = query[subject = 'A'];
p("Meaning of $xq=", $xq);
meaning($xq);
-----
Meaning of query='A[R]'
A #1
Meaning of $xq='A[R]'
A #1
Following is example of the $xd description and $xq query meaning. The m() is abbreviation of meaning() .
description 'R[A #, B #][]'[subject 'R'] =;
$xd = description[subject = 'R'];
m($xd) =; -- first
p("Meaning of $xq=", $xq, " after first $xd=", $xd);
m($xq);
m($xd) =; -- second
p("Meaning of $xq=", $xq, " after second $xd=", $xd);
m($xq);
-----
Meaning of $xq='A[R]' after first $xd='R[A #, B #][]'
A {#1, #2}
Meaning of $xq='A[R]' after second $xd='R[A #, B #][]'
A {#1, #2, #3}
It is permissible to use the set as parameter of m(...) function.
query 'B[R]'[subject 'B'] =;
$xqs = query '%[%R%]%';
p("Meaning of the set $xqs=", $xqs);
m($xqs);
-----
Meaning of the set $xqs={'A[R]', 'B[R]'}
{A {#1, #2, #3}, B {#1, #2, #3}}
The last fragment demonstrates a using of quote and unquote functions.
$xqs1 := unquote($xqs);
$xqs2 := quote(first($xqs1));
p("Meaning of first query ", $xqs2, " from ", $xqs);
m($xqs2);
-----
Meaning of first query 'A[R]' from {'A[R]', 'B[R]'}
A {#1, #2, #3}
Constructions 11
#po.S.new (...) ; Creates new program object. The S subject of this point-expression is name of program class.It is possibly to get fields of program class
or object:
#po.S.s ; It is access to s field of #po.S
program class.
Really the s is a static variable of the S Java class.
#po.S.n.s ; Is access to s field of #po.S.n
program
object.
It is very important to mark some features of work with int, double, boolean and String Java objects in Smans language. Such object and their types are expressed directly via real name. The int is expressed by simple number like 3, the double - by number with point like 34.123, the boolean - by either true or false word, the String - by '...' or word combination like "file1.txt" or first_textual_file. For example, look at {#po.java.lang.System.out}.println("file1.txt"). These object names cannot be subject of Smans point-expression. For example, to define length of "file1.txt" string, we need to use #po.java.lang.String.new("file1.txt").length(), the "file1.txt".length() is not correct.
Smans functions and procedures:
mapState(..., S). Procedure maps all the attributes of the
... program objects in database. Possible contraction is $ms(...,S).
state(...). Result of function is a mapping of all the
attributes
of the ... program objects. Possible contraction is $s(...).
Let's stop on the mapState and state. To realize
attributes of the program objects, they get public fields and invoke
the public getX()
methods that are without parameters. System takes the getX()
method
as virtual attribute with X name. The last optional parameter, S,
of mapState
may be single or double. A mapState(...,
single)
maps
program objects with the attribute values quoted like '...'.
For
a mapState(..., double) attribute values are enclosed in "...".
Examples 11
Example below demonstrates the using of a Date Java program object, more exactly its toString method, through the meaning() function.$date := DATE
'#po.java.util.Date.new().toString()';
"START {meaning($date)}";
-----
START DATE:Fri Oct 02 12:08:09 MSD 2009
$v := #po.java.util.Vector.new();
$v;
-----
#po.java.util.Vector.1;
Now we will add to Vector the three String objects with real names red, green, blue and print first Vector's element.
$v.addElement('red');
$v.addElement('green');
$v.addElement('blue');
$v0 := $v.elementAt(0);
$v0;
-----
red;
Following example demonstrates a using of the mapState()
procedure. Before mapState()
we create the point
class with two values, which represent identifiers of Point Java objects.
point {
#po.java.awt.Point.new(1,2),
#po.java.awt.Point.new(3,4)
} =;
mapState(point, quote);
pr(point);
-----
point {
#po.java.awt.Point.1[location
'java.awt.Point[x=1,y=2]',
x 1,
y 2],
#po.java.awt.Point.2[location
'java.awt.Point[x=3,y=4]',
x 3,
y 4]
};
$x := point[x=3,y=4];
$x.move(4,5);
state($x);
{$x}[] !=;
{$x}[quote(state($x))] =;
pr(point);
-----
{location:java.awt.Point[x=4,y=5], x 4, y 5}
point {
#po.java.awt.Point.1[location
'java.awt.Point[x=1,y=2]',
x 1,
y 2],
#po.java.awt.Point.2[location
'java.awt.Point[x=4,y=5]',
x 4,
y 5]
};
po #po.java.lang.String.new({'a','b','c'})
=;
$z = po;
$z;
-----
#po.java.lang.String.16,
#po.java.lang.String.20,
#po.java.lang.String.21;
As you saw example before, $z value is multitude of three String objects. We can invoke for $z other methods.
$z.toString();
$z.concat({"1","2","3"});
-----
{a, b, c}
{a1, a2, a3, b1, b2, b3, c1, c2, c3}
Below is example of executing the outside programs via current Java Runtime, for example calculator of the Microsoft Windows.
$xrun = #po.java.lang.Runtime.getRuntime();
"SEE CALCULATOR";
$xrun.exec("calc.exe");
-----
SEE CALCULATOR
Constructions 12
Descriptions
A: B: ... = ; Creates multilevel class, for example, A:B 'b'=.Class hierarchy is a tree of class names. Such names are separated
by ':' colon. The ':' colon sign is universal and may be used to
separate names with values also, for example A1:{'a1', A2:'a2'}=.
Each branch of a tree
ends up with a set of leaves or in our case a set of values. Values in
such
tree are not necessary in Smans language. That is we can create class
with
indefinite values, for example animal:dog=
. It is equal to empty dog
class, which belongs to animal
class. In context with tabular representation, empty dog table belongs to animal set of tables. It is
possible to set a relation directly for class names, not only for
values, for example, animal:dog[sound
'bark', size, color]=.
Queries
A{} ; This expression helps to select class name only, ignoring its values.Examples 12
Let us classify by Smans language the elements of the contact category with necessary properties: phone and address. Other affiliation, hobby, profession properties depends on the terminal subcategory.$base "notedb/mydata" !=;Following are few variants of query with correspondent results.
@category[@property]:contact[@property:phone]:{
known_person[@property:address]:{
relative[@property:affiliation],
fellow[@property:hobby,
@property:profession]
}
} =;
pr(@category:%);
pr(@category:);
pr(@category::);
-----To get the fellow elements of @category class we can use following statements:
@category:contact[@property:phone];
@category[@property]:contact[@property:phone];
@category[@property]:contact[@property:phone]:
known_person[@property:address]:{
fellow[@property:{hobby,profession}],
relative[@property:affiliation]
};
@category::fellow{};
@category::[@property::phone{}, @property::profession{}];
-----Now let's create contact complex class with usual names and relation defined by this class. The pr() prints this relation.
@category:contact:known_person:fellow;
@category:contact:known_person:fellow;
contact:known_person:{
relative #[phone #, address #, affiliation #],
fellow #[phone #, address #, hobby #, profession #]
} =;
pr(contact::);
-----Because fellow is a subclass, to print it we can use the ::fellow statement. The simple fellow query does not work.
contact[]:known_person[]:{
fellow[] #1[address #2,
hobby #1,
phone #2,
profession #1],
relative[] #1[address #1,
affiliation #1,
phone #1]
};
::fellow;
-----Below are some query variants for testing. First statement with % reflects all elements even if they do not have values. Second reflects only names. Third statement reflects all elements with values. Fourth gives last value element.
contact:known_person:fellow #1;
contact::%;
contact::*{};
contact::.;
contact::#;
-----Now let's get all the contacts featured by phone and profession .
contact:known_person{}:{
fellow{} #1,
relative{} #1
};
contact:known_person{}:{
fellow,
relative
};
contact:known_person:{
fellow #1,
relative #1
};
contact:known_person:relative #1;
contact::[phone, profession];
-----If we need to find all known_person except the contact namely fellow, we can use following statement.
contact:known_person:fellow #1;
{::known_person:: ! contact::fellow}.;
-----
contact:known_person{}:relative #1;
E Expression
Q Request in statement: Q; | =Q; | Q!=; | Q!=Q; | D=Q; | ?{Q,...};
D Description in statement: D=; | D=Q;
R|R 'r' Relation name in relation: R[E] | R 'r'[E]
A|B Simple class name (or term) in class: {A{'a',...},B{'b',...}} | A:{B:...,...}
'a'|'b' Class value (or term) in class: {A{'a',...},B{'b',...}} | A:{'a', B 'b',...}
A:B:... Complex class name in class: A:{B:...,...}.
A 'a'|B|'b' Element name in class: A{'a',...}|{B,...}|{'b',...}
Syntax notation in EBNF:
K Key symbol "$" | "'" | "#" | "." | "@" | "\"" | "*" | "%" | "(" | "{" | "[" | ")" | "}" | "]"
| " " | ":" | "`" | "/" | "-" | "=" | "<" | ">" | "!" | "&" | "|" | "?" | "," | ";"
C Non-key character
L Letter
D Digit
I Integer D+
N Number I | I.I | "0%"
W Word C(C|"."|"-")*
S Sequence "%"?(W"%"?)+ | "%"
Id Identifier "#" | "#"S
On Object name #po.L+("."L+)*(.I)?
Sv String value "'"(K|C)*"'"
(or single quoted string)
Vl Class value "." | N | Id | On | Sv
Sn String name "\""(K|C)*"\""
(or double quoted string)
An At-name "@"S
Nm Class name "*" | S | Sn | An | W(" "W)*
Tr Class term Vl | Nm
El Element name Tr | Nm Vl | Nm:El | Nm::El
Spn Specification name C+ | "'"(C|K-"'")+"'" | "\""(C|K-"\"")+"\""
Spc Specification "$"L+" "Spn | "$"Spn
Exp Expression El | Spc | Exp K | K Exp | Exp Exp |
Stm Statement Exp ("," Exp)*
Scr Script Stm (";" Stm)*
Expressions ordered by priority (with
special
symbols '|' and '...'): 1 -- ... | (: ... :) 1, 2Procedures
1 [Exp, ...] 2, 4, 6
1 {Exp, ...} | ?{Exp} 3, 4, 6
1 (Exp, ...) 4
2 Spc 1, 3, 7, 8
3 Nm | Vl 2, 4, 6, 9
4 W(Exp, ...) 2, 3, 4, 8
4 On(Exp, ...) 11
5 Nm Vl 0, 2, 3, 4
5 Nm:El | Nm::El 12
6 Exp{Exp, ...} 4, 12
6 Exp[Exp, ...] 2, 4, 6, 10
7 Exp/Exp | Exp//Exp 5
7 /Exp | Exp/ 5
8 - Exp | Exp - Exp | Exp - 4
Exp to Exp
9 Exp != Exp | Exp = Exp 4
9 Exp > Exp | Exp >= Exp 4
9 Exp < Exp | Exp <= Exp 4
10 = Exp 1, 4
11 Exp = Exp; 1, 6, 7
11 Exp == Exp; 6
11 Exp -= Exp; 6
11 Exp := Exp 7
12 Exp ! Exp 4
Exp except Exp
13 Exp & Exp 4
Exp intersect Exp
14 Exp | Exp 4
Exp union Exp
15 Exp != | Exp = 2, 6, 7
16 Exp, Exp 3, 4
17 Stm; Stm 4, 6
rt | readTable 2, 8Functions
p | print 3
pc | printClass 3
pr | printRelation 3
ps | printSchema 3
pt | printTable 3
pth | printTableHead 3
ptr | printTableRows 3
rc | renameColumn 8
ac | addColumn 8
dc | deleteColumn 8
ms | mapState 11
c | count 3
f | first 3
l | last 3
m | meaning 10
q | quote 10
uq | unquote 10
s | state 11