Symbol coder

Saturday 8 October 2011

How to install Linux, Mac OS X and Windows in a MacBook Pro


This is my simple algorithm to install the three operating systems:

1) Insert Mac OS X CD and create two partitions with  Utilities -> Disk Utilities in the boot CD installation menu: 66% of HD disk space will be destined to a Linux ext partition and the other 33% for a Mac OS file system with a GUID partition type in the options menu.

2) Continue installing Mac OS X in the 33% partition. After the installation, start Utilities -> Bootcamp and install Windows in the 66% partition in C: with a NTFS file system. (Select format NTFS partition quickly in Windows XP installation).

3) Windows will be installed getting the whole 66% partition. After it, insert the Ubuntu Linux installation CD. In the Ubuntu's main installation menu, select the first option and split the 66% partition in two parts in the way you want.

4) The Mac OS X install disk contains a Windows application called Bootcamp.exe. If you launch it, all the drivers for the Windows XP, Vista and 7 (32 and 64 bits)  will be installed.

Remarks: Although all OS will be installed properly in GRUB, Mac OS X must be started pressing ALT when booting the MacBook Pro.

Friday 2 September 2011

Fibonacci in assembler

Image: public domain

Last year, for training in my last exam about compilers I had to solve many problems about execution environments and assembler questions. One of them is this Fibonacci function written in recursive flat assembler for the WinEns2001 simulator, according to this algorithm in the ADA language:
 
function fib(n : integer) return integer is
begin
  if n < 2 then
    return n;
  else
    return fib(n-1) + fib(n-2);
  end if;
end fib;

and finally this is my solution in asm:

MOVE  #10000,.IX  ;Start address 
MOVE .IX,#12[.IX]  ;Link access 
MOVE #12,#11[.IX]  ;Input number 
ADD .IX,#10   ;Change execution environment 
MOVE .A,.IX 

ADD .PC,#4   ;Store branch in return address 
MOVE .A,#3[.IX] 
BR /FIBO   ;Jump to first Fibonacci sum 

EXIT: NOP 

SUB .IX,#10   ;Return to main execution environment 
MOVE .A,.IX 
WRSTR /LAB 
WRINT #10[.IX]   ;Display result 
HALT    ;Finish execution 

FIBO: NOP   ;First Fibonacci sum 

CMP #1[.IX],#3   ;Ready to finish if lower or equal than 2 
BN /EXITFIBO 

MOVE .IX,#12[.IX]  ;Update access link 
SUB #1[.IX],#1   ;fibo(n-1) 
MOVE .A,#11[.IX]  ;First sum's result in the next execution environment 
ADD .IX,#10   ;Change execution environment 
MOVE .A,.IX 
ADD .PC,#4   ;Prepare for the second sum 
MOVE .A,#3[.IX]  ;Store branch in return address 
BR /FIBO 

FIBO2: 

SUB .IX,#10   ;Restore execution environment 
MOVE .A,.IX 
MOVE #10[.IX],#8[.IX]  ;Move first base case 
MOVE .IX,#12[.IX]  ;Update access link 
SUB #1[.IX],#2   ;Calculates fibo(n-2) 
MOVE .A,#11[.IX]  ;Second sum's result 
ADD .IX,#10   ;Change execution environment 
MOVE .A,.IX 
ADD .PC,#4   ;Prepare for the the third sum 
MOVE .A,#3[.IX]  ;Store branch in return address 
BR /FIBO 

FIBO3: 

SUB .IX,#10   ;Restore execution environment 
MOVE .A,.IX 
ADD #10[.IX],#8[.IX]  ;Sum fibo(n-1) + fibo(n-2) 
MOVE .A,[.IX]   ;Restore return address 
ADD .IX,#3 
BR [.A] 

EXITFIBO: 

MOVE #1,[.IX]   ;Base case 
ADD .IX,#3   ;Return to return address 
BR [.A] 


LAB: DATA "THE FIBONACCI IS:"

Wednesday 10 August 2011

Expression analyzer

According to Louden's chapter 4, I wrote this C++ class based on his standard C functions. This class performs a recursive top-down syntax parser and calculation. Basically it is based in this BNF grammar:

exp → exp opadd term | term
opadd → + | -
term → term opmult factor | factor
opmult → * | /
factor → (exp) | integer

which must be translated to EBNF to code the recursive class:

exp → term {oppadd term }
opadd → + | -
term → factor {opmult factor }
opmult → * | /
factor → (exp) | integer
Consenquently, the source code for this parser is shown below:
// Integer Expression Analyzer
// (C) Carlos Jiménez de Parga
// Released under GPL v3.0 terms
#include
#include 
#include 
#include 

// The analyzer class
 class Analyzer{
  private: char token;    // Current analyzed token 
  int exp_count;      // Current token count 
  std::string expr;   // The analyzed expresion string  
  void match(const char expectedToken); 
  int term(void); 
  int factor(void); 
  std::string getNumber(void); 
  // Convert string to integer
  public: 
  Analyzer(const std::string &expression); 
  ~Analyzer(); 
  int exp() ; 
  bool eol();
};
// Exception handling class 
class Exception:public std::exception{
 private: 
  std::string what_str;
  public: Exception(std::string excep);
  ~Exception() throw(){} virtual const char* what() const throw();
 };
 Exception::Exception(const std::string excep)
 {
   what_str = excep + "\n";
 }
 const char* Exception::what() const throw()
 {   
   return what_str.c_str();
 }
 // Constructor
 Analyzer::Analyzer(const std::string &expression)
 {   expr = expression; 
   exp_count = 0; 
   token = expr[exp_count++];
 }
 // Destructor
 Analyzer::~Analyzer()
 { 
  std::cout << "Destroyed" << std::endl;
 }
 // Convert lexem to integerstd::string Analyzer::getNumber()
 { 
  std::string token_conv;  
  --exp_count;  
  while (isdigit(expr[exp_count])) 
  {   
   token_conv.push_back(expr[exp_count]);  
   exp_count++; 
  }   
   return token_conv; 
 }// Check current token and advance pointer
 
 void Analyzer::match(const char expectedToken) 
 { 
  if (token == expectedToken)   
   token = expr[exp_count++]; 
  else throw Exception("No expected token->line 74");}
 // First non-terminal call. Performs + and -int 
 Analyzer::exp()
  { 
  int temp = term(); while ((token=='+') || (token=='-'))  switch(token)  
  {   
   case '+':   
     match('+');   
     temp+=term();    
    break;   
   case '-':    
    match('-');    
    temp-=term();    
    break;  
  }  
  return temp;
 } 
  // Second non-terminal call. Performs * and /
 int Analyzer::term() 
 { 
  int temp = factor(); 
  while ((token=='*') || (token=='/'))  switch(token)  
  {   case '*':
       match('*');
       temp*=factor();
       break;
    case '/':
       match('/');
       temp/=factor();
       break;     
  }  
  return temp;
 } 
 // Call to terminals ( ) and integers 
 int Analyzer::factor() 
 { 
  int temp; 
  if (token=='(')
   {  
    match('(');  
    temp = exp();  
    match(')'); 
   } else if (isdigit(token)) 
   {  
    temp = atoi(getNumber().c_str());  
    token = expr[exp_count++]; 
   } else throw Exception("No item found->line 124"); 
   return temp;
 }
 // End of line is reached
 bool Analyzer::eol()
 { 
  return token == 0; 
 }

 int main(int argc, char **argv)
 { 
  int result; std::string exp,key;  
  // Test expression int x = 22+(5)*(5/3+1)*7
  -235+789*2/12+(6*(34+2)-1)+
  25/(2-123)+ 14*((1+23)/2/2/2*(1+1+(2-3)*4+1+
  ((((56+12*100))))))/100+11;  // Prints test expression 
  std::cout << "The example expression is="  << x << std::endl;  
   do // Repeat until not 
    {   
     std::cout << "Enter an expression with +,-,* and /" << std::endl;
     std::cin << exp;    //exp = "22+(5)*(5/3+1)*7-235+789
     *2/12+(6*(34+2)-1)+25/(2-123)+  //14*((1+23)/2/2/2*(1+1+(2-3)
     *4+1+((((56+12*100))))))/100+11";    
     // Do calculation  
     try{   Analyzer analyzer(exp);   
       result = analyzer.exp();   
       if (analyzer.eol()) // EOL is reached    
      std::cout << "The result is = " << result << std::endl;
     else throw Exception("Not eol reached->line 127");     
    } catch(std::exception &e)  
    {   
     std::cerr << "Error: " << e.what();  
     return 1;  
    }  std::cout << "Another expresion?:";
       std::cin << key; 
   } while (key == "y"); 
   return 0;
}

Sunday 31 July 2011

Dijkstra in Lisp


Image: public domain 

The Dijkstra's algorithm was conceived by Edsger Dijkstra, a computer scientist who solved the single-source shortest path for a graph. The basic idea of the algorithm is to find the shortest paths from one node to others. It is usually used in network routing, air traffic, logistics and Artificial Intelligence.
Here below is my implementation of the Dijkstra's algorithm in the Lisp language:

(defun dijkstra (s c n o)
(setq INF 9999999) ; Infinite
(setq D (make-array s))
(setq m (list o))

; Initialize D vector
(do ((i 0))
((= i s)) ; if adjacent
 (if (>= (aref c o i) 0)
  (setf (aref D i) (aref c o i))
  (setf (aref D i) INF)
 )
(setq i (+ i 1))
)
; Do Dijkstra for N - 1 items
(do ((j 1))
((= j s))

(setq exit nil)
(do ((w 0)) ; select the first of D
 ((= w s)) ; not in candidate's list
 (when (and (eq (member w m) nil)(eq exit nil))
  (setq minW w)
  (setq valW (aref D w))
  (setq exit t)
 )
(setq w (+ w 1))
)

(do ((w 0)) ; select the minimum of D
 ((= w s)) ; not in candidate's list
 (when (eq (member w m) nil)
  (when (< (aref D w) valW)
   (setq minW w)
   (setq valW (aref D w))
  )
 )
(setq w (+ w 1))
)
; Add to candidate's list
(setq m (append m (list minW)))

; Iterate to update the items
(do ((v 0))
 ((= v s))
 (if (and (> (aref c minW v) 0)(eq (member v m) nil))
  (setf (aref D v) (min (aref D v)(+(aref D minW)(aref c minW v)))))
 (setq v (+ v 1))
)
(setq j (+ j 1))
)
D ; return D vector
)