segunda-feira, 19 de fevereiro de 2007

Perl and Unicode


#!/usr/bin/env perl
#
use strict;
use charnames ':full';
use utf8;

# First, let's print the source code.
open THIS, $0;
print $_ while (<THIS>);

# Get the vector elements sum. We use the Sigma greek letter.
sub Σ
{
my ($accum) = shift;

foreach(@_)
{
$accum += $_;
}
return $accum;
}

# My Day is done!
# But Gauss would do it better!
# We can see that perl allows any
# Alphabet caracter to be used, but any symbol
# is reserverd. This is the case of integral symbols
# ∫, ∬, ∭, ∮, ∯, ∰, ∳, ∲. and even the Summantion sign ∑
# Note that this is not the greek sigma letter. Perl is smart, hum?

my @Ϯ = 1 .. 100;
my $ΔU = Σ @Ϯ; # Σ is not ∑. (Sigma and summantion sign).

print "The Summation from one to a handred is $ΔU.\n";

# Energy Funcion Ψ.
# It goes from ± a radius around
# the center.
sub Ψ
{
my ($α,$β,$γ) = @_[0..2];
return $α**2 + $β**2 + $γ**2;
}



# My runic letter Gar
my $ᚸ = Ψ(2.3, 234.0, 23.4);

# Listing day in Japanese, from Sunday to Saturday
my @Ա = qw/㈰ ㈪ ㈫ ㈬ ㈭ ㈮ ㈯/;

# A dictionary.
my %Ծ =
(
"㈰" => ["Sun", "Sunday"],
"㈪" => ["Moon", "Monday"],
"㈫ " => ["Fire", "Tuesday"],
"㈬" => ["Water", "Wednesday"],
"㈭" => ["Wood", "Thursday"],
"㈮" => ["Metal", "Friday"],
"㈯" => ["Earth", "Saturday"],
);


# Now, lets print the sign for Astrological sign.

my $signs = join ", ", map { chr(ord("♈") + $_ - 1) } 1..12;

print "This is a list with the signs $signs.\n";

foreach my $Ʃ (@Ա)
{
print "$Ʃ is the Japanese symbol for $Ծ{$Ʃ}->[0] element, also $Ծ{$Ʃ}->[1] week\'s day.\n";
}




quarta-feira, 22 de novembro de 2006

String character permutation.



/*
* File: heap.c
* Author: cassius
*
* Created on 19 de Novembro de 2006, 22:27
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



static void print_recursive(char* str, int pos, int length)
{
int k;
char first, current;

if(pos >= (length-1) )
fprintf(stdout, "%s ", str);
else
{
first = str[pos];

for(k = pos; k < length; k++)
{
/* swap chars */
current = str[k];
str[pos] = current;
str[k] = first;

print_recursive(str, pos + 1, length);
/* swap it back. */
str[k] = current;
}
str[pos] = first;
}
}

void print(char* str)
{
int len = strlen(str);

print_recursive(str, 0, len);
fprintf(stdout, ".\n");
}


/*
*
*/
int
main(int argc, char** argv) {
char max_str[100];
fprintf(stdout, "Please, digite a word.\n");

fscanf(stdin, "%s ", max_str);

print(max_str);
fprintf(stdout, "Exiting ...");

return (EXIT_SUCCESS);
}

sábado, 18 de novembro de 2006

ANSI C Conditional operator grammar analysis.

A friend I meet at C language lists send me a question about compiling problems with
the conditional operator.

These lines:
int main(){
int a = 10 , b ;
a >= 5 ? b =100: b=200;
}


Did not compile or give a warning, depending on the compiler, of course. But with a little change:


int main(){
int a = 10 , b ;
a >= 5 ? b =100: (b=200);
}


The warnings/erros stoped. The question is why?

Well, before start, I change the code a little ...

int main(){
int a = 10 , b ;
a >= 5
? b =100
: b=200;
}


... and a compile it again (with lcc-wi32). The error where related to the last assignment.

By that time, I was aware that I would need to search for the grammar definition of this operator. In the absence of a ANSI C spec, I search the "The ANSI C Language", Kernighan & Ritchie, whose had an Appendix with ANSI C grammar and comments.

Section A.7.16 the grammar defines the conditional operator as:

conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression


Hum, the third argument is not an expression. It is in fact, redefined as a conditional expression. Probably, in order to allow chained use. Following the definitions, the parser will end to an primary-expression. The primary expression will the resolve, as the a is an identifier.

The compiler will evaluate this as an conditional expression:
a >= 5 ? b =100: b
And, will encounter the assignment and will interpreter this as an attempt to change
the conditional-expression result. Witch is invalid of course. Or, something like that:

(a >= 5 ? b =100: b) = 200;

I tried it in my compiler, and it returned the same error.

Okay, but and about the second try? Why it works? Simple: As the parenthesis are around, it will force the expression b = 200 to be evaluated first.


About the C grammar, you can find it also at the internet at the site http://www.lysator.liu.se/c/ANSI-C-grammar-y.html#conditional-expression, as a YACC grammar definition file. Starting from the beginning of the conditional expression, we have:

conditional_expression -> logical_or_expression -> logical_and_expression -> inclusive_or_expression -> exclusive_or_expression -> and_expression -> equality_expression -> relational_expression -> shift_expression -> additive_expression -> multiplicative_expression -> cast_expression -> unary_expression -> postfix_expression -> primary_expression and finally the IDENTIFIER. At the example give above, it will be the 'b'.

quarta-feira, 15 de novembro de 2006

Scrambling a sorted array.


/*
* File: newmain.c
* Author: cassius
*
* Created on 15 de Novembro de 2006, 13:22
*/

#include <stdio.h>
#include <stdlib.h>

const char ptr[] ="string";

typedef struct
{
const char *c;
int i;
}test_struct;

test_struct s={ptr,10};


/* Only to take control of it */
#define DEFAULT_ARRAY_SIZE 10
#define MAX_ARRAY_PERMITED_SIZE 1024

/*
*
*/
int
main(int argc, char** argv) {
int *array = NULL;
int k = 0;
int length = DEFAULT_ARRAY_SIZE;
int arg_pos = 1;
double n;

/* If you want to force the same resoults, use -seed num to set a seed
to the pseudo random sequence.
*/
while(arg_pos < argc) {
if( (strcmp(argv[arg_pos],"--seed") == 0) && (argc - arg_pos >= 2 ) ) {
int seed;

arg_pos++;
seed = atoi(argv[arg_pos]);
srand(seed);
} else if( (strcmp(argv[arg_pos],"--length") == 0) && (argc - arg_pos >= 2 ) ) {
int user_length;
arg_pos++;
user_length = atoi(argv[arg_pos]);
if( (user_length < 1) || (user_length > MAX_ARRAY_PERMITED_SIZE ) )
fprintf(stdout, "Invalid length. Assuming default value of %d.\n",length);
else
length = user_length;

}
arg_pos++; /* bypass argment name or last args processed */
}

/* Suppouse we use only 100 positons, for now */
array = (int*)malloc(sizeof(int)*length);

if(array == NULL)
{
fprintf(stderr, "No memory could be allocated. Exiting... ");
return (EXIT_FAILURE);
}

for(k = 0; k < length; k++ )
array[k] = k;

/* Now, scramble the array. The process is simple. The k variable points to
the end of the array. We choose randomically between all positions bellow
k. This position must be swapped with k. And the process goes on until
the the start of the array.
Warning: Although */


for(k = (length-1); k > 0;k-- )
{
int temp_int = array[k];
int old_pos = rand() % k;

array[k] = array[old_pos];
array[old_pos] = temp_int;
}

/* Print the array. */

fprintf(stdout, "[");
for(k = 0; k < length; k++)
{
char term = k == (length -1) ? ']' : ',';

fprintf(stdout, "%d%c",array[k],term);
}
fprintf(stdout, "\n");

return (EXIT_SUCCESS);
}


Quem sou eu

Minha foto
I used to work with embedded software and digital design. Now my career is about to turn in a complete different direction ...