[Avida-SVN] r2459 - development/source/script

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Mon Mar 17 12:57:20 PDT 2008


Author: brysonda
Date: 2008-03-17 15:57:20 -0400 (Mon, 17 Mar 2008)
New Revision: 2459

Modified:
   development/source/script/ASCoreLib.cc
   development/source/script/ASTree.h
   development/source/script/AvidaScript.h
   development/source/script/cASFunction.h
   development/source/script/cASLibrary.cc
   development/source/script/cASLibrary.h
   development/source/script/cDirectInterpretASTVisitor.cc
   development/source/script/cSemanticASTVisitor.cc
Log:
AS:
Semantic check and call library functions.  Basic print and println library methods.

Modified: development/source/script/ASCoreLib.cc
===================================================================
--- development/source/script/ASCoreLib.cc	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/ASCoreLib.cc	2008-03-17 19:57:20 UTC (rev 2459)
@@ -32,6 +32,11 @@
 namespace ASCoreLib {
   void print(const cString& value)
   {
+    std::cout << value;
+  }
+  
+  void println(const cString& value)
+  {
     std::cout << value << std::endl;
   }
 };
@@ -40,4 +45,5 @@
 void RegisterASCoreLib(cASLibrary* lib)
 {
   lib->RegisterFunction(new tASFunction<void (const cString&)>(&ASCoreLib::print, "print"));
+  lib->RegisterFunction(new tASFunction<void (const cString&)>(&ASCoreLib::println, "println"));
 }

Modified: development/source/script/ASTree.h
===================================================================
--- development/source/script/ASTree.h	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/ASTree.h	2008-03-17 19:57:20 UTC (rev 2459)
@@ -35,9 +35,9 @@
 #include "tManagedPointerArray.h"
 
 
+class cASFunction;
 class cASTVisitor;
 
-
 class cASFilePosition
 {
 private:
@@ -490,10 +490,11 @@
   sASTypeInfo m_type;
   int m_id;
   bool m_global;
+  const cASFunction* m_func;
   
 public:
   cASTFunctionCall(const cASFilePosition& fp, const cString& name)
-    : cASTNode(fp), m_name(name), m_args(NULL), m_type(AS_TYPE_INVALID), m_id(-1), m_global(false) { ; }
+    : cASTNode(fp), m_name(name), m_args(NULL), m_type(AS_TYPE_INVALID), m_id(-1), m_global(false), m_func(NULL) { ; }
   ~cASTFunctionCall() { delete m_args; }
   
   const cString& GetName() const { return m_name; }
@@ -507,6 +508,10 @@
   inline int GetFuncID() const { return m_id; }
   inline bool IsFuncGlobal() const { return m_global; }
   inline void SetFunc(int in_id, bool global) { m_id = in_id; m_global = global; }
+  
+  inline const cASFunction* GetASFunction() const { return m_func; }
+  inline bool IsASFunction() const { return (m_func); }
+  inline void SetASFunction(const cASFunction* func) { m_func = func; }
 
   bool HasArguments() const { return (m_args); }
   

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/AvidaScript.h	2008-03-17 19:57:20 UTC (rev 2459)
@@ -129,6 +129,7 @@
   AS_SEMANTIC_ERR_BUILTIN_CALL_SIGNATURE_MISMATCH,
   AS_SEMANTIC_ERR_CANNOT_CAST,
   AS_SEMANTIC_ERR_CANNOT_COMPARE,
+  AS_SEMANTIC_ERR_CANNOT_OVERRIDE_LIB_FUNCTION,
   AS_SEMANTIC_ERR_FUNCTION_CALL_SIGNATURE_MISMATCH,
   AS_SEMANTIC_ERR_FUNCTION_DEFAULT_CALL_INVALID,
   AS_SEMANTIC_ERR_FUNCTION_DEFAULT_VARIABLE_REF_INVALID,
@@ -181,6 +182,8 @@
   AS_EXIT_FAIL_PARSE,
   AS_EXIT_FAIL_SEMANTIC,
   AS_EXIT_FAIL_INTERPRET,
+  
+  AS_EXIT_INTERNAL_ERROR,
 
   AS_EXIT_UNKNOWN
 };

Modified: development/source/script/cASFunction.h
===================================================================
--- development/source/script/cASFunction.h	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/cASFunction.h	2008-03-17 19:57:20 UTC (rev 2459)
@@ -25,7 +25,9 @@
 #ifndef cASFunction_h
 #define cASFunction_h
 
+#include "avida.h"
 #include "AvidaScript.h"
+
 #include "cString.h"
 
 
@@ -40,7 +42,7 @@
       char m_char;
       int m_int;
       double m_float;
-      const cString* m_string;
+      cString* m_string;
     };
     
   public:
@@ -51,19 +53,15 @@
     void Set(int val) { m_int = val; }
     void Set(double val) { m_float = val; }
     void Set(cString* val) { m_string = val; }
+    void Set(const cString& val) { m_string = new cString(val); }
     
-    bool Get(bool) const { return m_bool; }
-    char Get(char) const { return m_char; }
-    int Get(int) const { return m_int; }
-    double Get(double) const { return m_float; }
-    const cString& Get(const cString&) const { return *m_string; }
+    template<typename T> inline T Get() const { Avida::Exit(AS_EXIT_INTERNAL_ERROR); return m_int; }
   };
   
   
 protected:
   cString m_name;
   sASTypeInfo m_rtype;
-  cParameter m_rvalue;
   
   
 public:
@@ -72,15 +70,23 @@
   
   const cString& GetName() const { return m_name; }
 
-  virtual int GetArity() = 0;
+  virtual int GetArity() const = 0;
   const sASTypeInfo& GetReturnType() const { return m_rtype; }
   virtual const sASTypeInfo& GetArgumentType(int arg) const = 0;
   
-  virtual void Call(cParameter args[]) = 0;
-  const cParameter& GetReturnValue() const { return m_rvalue; }
+  virtual cParameter Call(cParameter args[]) const = 0;
 };
 
 
+template<> inline bool cASFunction::cParameter::Get<bool>() const { return m_bool; }
+template<> inline char cASFunction::cParameter::Get<char>() const { return m_char; }
+template<> inline int cASFunction::cParameter::Get<int>() const { return m_int; }
+template<> inline double cASFunction::cParameter::Get<double>() const { return m_float; }
+template<> inline const cString& cASFunction::cParameter::Get<const cString&>() const { return *m_string; }
+template<> inline const cString* cASFunction::cParameter::Get<const cString*>() const { return m_string; }
+template<> inline cString* cASFunction::cParameter::Get<cString*>() const { return m_string; }
+
+
 template<typename FunctionType> class tASFunction;
 
 
@@ -101,13 +107,14 @@
     m_signature = AvidaScript::TypeOf<Arg1Type>();
   }
   
-  int GetArity() { return 1; }
+  int GetArity() const { return 1; }
   const sASTypeInfo& GetArgumentType(int arg) const { return m_signature; }
   
-  void Call(cParameter args[])
+  cParameter Call(cParameter args[]) const
   {
-    void* x = NULL;
-    m_rvalue.Set((*m_func)(args[0].Get((Arg1Type)x)));
+    cParameter rvalue;
+    rvalue.Set((*m_func)(args[0].Get<Arg1Type>()));
+    return rvalue;
   }
 };
                   
@@ -129,13 +136,14 @@
     m_signature = AvidaScript::TypeOf<Arg1Type>();
   }
   
-  int GetArity() { return 1; }
+  int GetArity() const { return 1; }
   const sASTypeInfo& GetArgumentType(int arg) const { return m_signature; }
   
-  void Call(cParameter args[])
+  cParameter Call(cParameter args[]) const
   {
-    void* x = NULL;
-    (*m_func)(args[0].Get((Arg1Type)x));
+    (*m_func)(args[0].Get<Arg1Type>());
+    
+    return cParameter();
   }
 };
 

Modified: development/source/script/cASLibrary.cc
===================================================================
--- development/source/script/cASLibrary.cc	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/cASLibrary.cc	2008-03-17 19:57:20 UTC (rev 2459)
@@ -33,9 +33,9 @@
 }
 
 
-bool cASLibrary::RegisterFunction(cASFunction* func)
+bool cASLibrary::RegisterFunction(const cASFunction* func)
 {
-  cASFunction* old_func = NULL;
+  const cASFunction* old_func = NULL;
   bool found = m_fun_dict.Find(func->GetName(), old_func);
   
   if (found) {

Modified: development/source/script/cASLibrary.h
===================================================================
--- development/source/script/cASLibrary.h	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/cASLibrary.h	2008-03-17 19:57:20 UTC (rev 2459)
@@ -39,7 +39,7 @@
   // --------  Internal Variables  --------
   tArray<sObjectEntry*> m_obj_tbl;
   tDictionary<int> m_obj_dict;
-  tDictionary<cASFunction*> m_fun_dict;
+  tDictionary<const cASFunction*> m_fun_dict;
 
   
   // --------  Private Constructors  --------
@@ -52,9 +52,11 @@
   ~cASLibrary();
 
   bool LookupObject(const cString& obj_name, int& obj_id);
-  bool LookupFunction(const cString& name, cASFunction*& func);
+  bool LookupFunction(const cString& name, const cASFunction*& func) { return m_fun_dict.Find(name, func); }
+  
+  bool HasFunction(const cString& name) const { return m_fun_dict.HasEntry(name); }
 
-  bool RegisterFunction(cASFunction* func);
+  bool RegisterFunction(const cASFunction* func);
   
   
 private:

Modified: development/source/script/cDirectInterpretASTVisitor.cc
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.cc	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/cDirectInterpretASTVisitor.cc	2008-03-17 19:57:20 UTC (rev 2459)
@@ -30,6 +30,7 @@
 #include "avida.h"
 #include "AvidaScript.h"
 
+#include "cASFunction.h"
 #include "cStringUtil.h"
 #include "cSymbolTable.h"
 
@@ -808,104 +809,162 @@
 
 void cDirectInterpretASTVisitor::VisitFunctionCall(cASTFunctionCall& node)
 {
-  // Save previous scope information
-  cSymbolTable* prev_symtbl = m_cur_symtbl;
-  
-  // Get function information
-  cSymbolTable* func_src_symtbl = node.IsFuncGlobal() ? m_global_symtbl : m_cur_symtbl;
-  int fun_id = node.GetFuncID();
-  
-  // Set current scope to the function symbol table
-  cSymbolTable* func_symtbl = func_src_symtbl->GetFunctionSymbolTable(fun_id);
-  int sp = m_sp + prev_symtbl->GetNumVariables();
-  m_call_stack.Resize(m_call_stack.GetSize() + func_symtbl->GetNumVariables());
-  for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
-    switch (func_symtbl->GetVariableType(i).type) {
-      case TYPE(ARRAY):       m_call_stack[sp + i].as_array = new cLocalArray; break;
-      case TYPE(BOOL):        m_call_stack[sp + i].as_bool = false; break;
-      case TYPE(CHAR):        m_call_stack[sp + i].as_char = 0; break;
-      case TYPE(INT):         m_call_stack[sp + i].as_int = 0; break;
-      case TYPE(FLOAT):       m_call_stack[sp + i].as_float = 0.0; break;
-      case TYPE(MATRIX):      m_call_stack[sp + i].as_matrix = NULL; break;
-      case TYPE(OBJECT_REF):  m_call_stack[sp + i].as_ref = NULL; break;
-      case TYPE(STRING):      m_call_stack[sp + i].as_string = NULL; break;
-      default: break;
+  if (node.IsASFunction()) {
+    // Call internal function
+    const cASFunction* func = node.GetASFunction();
+    
+    // Setup arguments
+    cASFunction::cParameter* args = new cASFunction::cParameter[func->GetArity()];
+    tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
+    cASTNode* an = NULL;
+    for (int i = 0; i < func->GetArity(); i++) {
+      an = cit.Next();
+      an->Accept(*this);
+     
+      switch (func->GetArgumentType(i).type) {
+        case TYPE(BOOL):        args[i].Set(asBool(m_rtype, m_rvalue, node)); break;
+        case TYPE(CHAR):        args[i].Set(asChar(m_rtype, m_rvalue, node)); break;
+        case TYPE(FLOAT):       args[i].Set(asFloat(m_rtype, m_rvalue, node)); break;
+        case TYPE(INT):         args[i].Set(asInt(m_rtype, m_rvalue, node)); break;
+        case TYPE(STRING):      args[i].Set(asString(m_rtype, m_rvalue, node)); break;
+          
+        default:
+          INTERPRET_ERROR(INTERNAL);
+      }
     }
-  }
-  
-  // Process the arguments to the function
-  tListIterator<cASTVariableDefinition> sit = func_src_symtbl->GetFunctionSignature(fun_id)->Iterator();
-  tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
-  cASTVariableDefinition* arg_def = NULL;
-  while ((arg_def = sit.Next())) {
-    cASTNode* arg = cit.Next();
-    if (arg) arg->Accept(*this);
-    else arg_def->GetAssignmentExpression()->Accept(*this);
     
-    int var_id = arg_def->GetVarID();
+    // Call the function
+    cASFunction::cParameter rvalue = func->Call(args);
 
-    switch (m_cur_symtbl->GetVariableType(var_id).type) {
-      case TYPE(ARRAY):       m_call_stack[sp + var_id].as_array = asArray(m_rtype, m_rvalue, node); break;
-      case TYPE(BOOL):        m_call_stack[sp + var_id].as_bool = asBool(m_rtype, m_rvalue, node); break;
-      case TYPE(CHAR):        m_call_stack[sp + var_id].as_char = asChar(m_rtype, m_rvalue, node); break;
-      case TYPE(FLOAT):       m_call_stack[sp + var_id].as_float = asFloat(m_rtype, m_rvalue, node); break;
-      case TYPE(INT):         m_call_stack[sp + var_id].as_int = asInt(m_rtype, m_rvalue, node); break;
-      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-      case TYPE(STRING):
-        {
-          m_call_stack[sp + var_id].as_string = asString(m_rtype, m_rvalue, node);
-        }
-        break;
+    // Handle the return value
+    switch (node.GetType().type) {
+      case TYPE(BOOL):        m_rvalue.as_bool = rvalue.Get<bool>(); break;
+      case TYPE(CHAR):        m_rvalue.as_char = rvalue.Get<char>(); break;
+      case TYPE(FLOAT):       m_rvalue.as_float = rvalue.Get<double>(); break;
+      case TYPE(INT):         m_rvalue.as_int = rvalue.Get<int>(); break;
+      case TYPE(STRING):      m_rvalue.as_string = rvalue.Get<cString*>(); break;
+      case TYPE(VOID):        break;
         
       default:
         INTERPRET_ERROR(INTERNAL);
     }
-  }
-  
-  
-  // Execute the function
-  m_cur_symtbl = func_symtbl;
-  m_sp = sp;
-  func_src_symtbl->GetFunctionDefinition(fun_id)->Accept(*this);
-  
-  // Handle function return value
-  switch (node.GetType().type) {
-    case TYPE(ARRAY):       m_rvalue.as_array = asArray(m_rtype, m_rvalue, node); break;
-    case TYPE(BOOL):        m_rvalue.as_bool = asBool(m_rtype, m_rvalue, node); break;
-    case TYPE(CHAR):        m_rvalue.as_char = asChar(m_rtype, m_rvalue, node); break;
-    case TYPE(FLOAT):       m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node); break;
-    case TYPE(INT):         m_rvalue.as_int = asInt(m_rtype, m_rvalue, node); break;
-    case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - return
-    case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - return
-    case TYPE(STRING):      m_rvalue.as_string = asString(m_rtype, m_rvalue, node); break;
-    case TYPE(VOID):        break;
+    m_rtype = node.GetType();
+    
+    // Clean up arguments
+    for (int i = 0; i < func->GetArity(); i++) {
+      switch (func->GetArgumentType(i).type) {
+        case TYPE(BOOL):    break;
+        case TYPE(CHAR):    break;
+        case TYPE(FLOAT):   break;
+        case TYPE(INT):     break;
+        case TYPE(STRING):  delete args[i].Get<cString*>(); break;
+          
+        default:
+          INTERPRET_ERROR(INTERNAL);
+      }
+    }
+    delete [] args;
+    
+  } else {
+    // Save previous scope information
+    cSymbolTable* prev_symtbl = m_cur_symtbl;
+    
+    // Get function information
+    cSymbolTable* func_src_symtbl = node.IsFuncGlobal() ? m_global_symtbl : m_cur_symtbl;
+    int fun_id = node.GetFuncID();
+    
+    // Set current scope to the function symbol table
+    cSymbolTable* func_symtbl = func_src_symtbl->GetFunctionSymbolTable(fun_id);
+    int sp = m_sp + prev_symtbl->GetNumVariables();
+    m_call_stack.Resize(m_call_stack.GetSize() + func_symtbl->GetNumVariables());
+    for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
+      switch (func_symtbl->GetVariableType(i).type) {
+        case TYPE(ARRAY):       m_call_stack[sp + i].as_array = new cLocalArray; break;
+        case TYPE(BOOL):        m_call_stack[sp + i].as_bool = false; break;
+        case TYPE(CHAR):        m_call_stack[sp + i].as_char = 0; break;
+        case TYPE(INT):         m_call_stack[sp + i].as_int = 0; break;
+        case TYPE(FLOAT):       m_call_stack[sp + i].as_float = 0.0; break;
+        case TYPE(MATRIX):      m_call_stack[sp + i].as_matrix = NULL; break;
+        case TYPE(OBJECT_REF):  m_call_stack[sp + i].as_ref = NULL; break;
+        case TYPE(STRING):      m_call_stack[sp + i].as_string = NULL; break;
+        default: break;
+      }
+    }
+    
+    // Process the arguments to the function
+    tListIterator<cASTVariableDefinition> sit = func_src_symtbl->GetFunctionSignature(fun_id)->Iterator();
+    tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
+    cASTVariableDefinition* arg_def = NULL;
+    while ((arg_def = sit.Next())) {
+      cASTNode* arg = cit.Next();
+      if (arg) arg->Accept(*this);
+      else arg_def->GetAssignmentExpression()->Accept(*this);
       
-    default:
-      INTERPRET_ERROR(INTERNAL);
-  }
-  m_rtype = node.GetType();
+      int var_id = arg_def->GetVarID();
 
-  // Clean up variables in the current scope
-  for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
-    switch (func_symtbl->GetVariableType(i).type) {
-      case TYPE(ARRAY):       m_call_stack[sp + i].as_array->RemoveReference(); break;
-      case TYPE(BOOL):        break;
-      case TYPE(CHAR):        break;
-      case TYPE(INT):         break;
-      case TYPE(FLOAT):       break;
-      case TYPE(MATRIX):      break; // @TODO - cleanup scope
-      case TYPE(OBJECT_REF):  delete m_call_stack[sp + i].as_ref; break;
-      case TYPE(STRING):      delete m_call_stack[sp + i].as_string; break;
-      default: break;
+      switch (m_cur_symtbl->GetVariableType(var_id).type) {
+        case TYPE(ARRAY):       m_call_stack[sp + var_id].as_array = asArray(m_rtype, m_rvalue, node); break;
+        case TYPE(BOOL):        m_call_stack[sp + var_id].as_bool = asBool(m_rtype, m_rvalue, node); break;
+        case TYPE(CHAR):        m_call_stack[sp + var_id].as_char = asChar(m_rtype, m_rvalue, node); break;
+        case TYPE(FLOAT):       m_call_stack[sp + var_id].as_float = asFloat(m_rtype, m_rvalue, node); break;
+        case TYPE(INT):         m_call_stack[sp + var_id].as_int = asInt(m_rtype, m_rvalue, node); break;
+        case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+        case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+        case TYPE(STRING):
+          {
+            m_call_stack[sp + var_id].as_string = asString(m_rtype, m_rvalue, node);
+          }
+          break;
+          
+        default:
+          INTERPRET_ERROR(INTERNAL);
+      }
     }
+    
+    
+    // Execute the function
+    m_cur_symtbl = func_symtbl;
+    m_sp = sp;
+    func_src_symtbl->GetFunctionDefinition(fun_id)->Accept(*this);
+    
+    // Handle function return value
+    switch (node.GetType().type) {
+      case TYPE(ARRAY):       m_rvalue.as_array = asArray(m_rtype, m_rvalue, node); break;
+      case TYPE(BOOL):        m_rvalue.as_bool = asBool(m_rtype, m_rvalue, node); break;
+      case TYPE(CHAR):        m_rvalue.as_char = asChar(m_rtype, m_rvalue, node); break;
+      case TYPE(FLOAT):       m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node); break;
+      case TYPE(INT):         m_rvalue.as_int = asInt(m_rtype, m_rvalue, node); break;
+      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - return
+      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - return
+      case TYPE(STRING):      m_rvalue.as_string = asString(m_rtype, m_rvalue, node); break;
+      case TYPE(VOID):        break;
+        
+      default:
+        INTERPRET_ERROR(INTERNAL);
+    }
+    m_rtype = node.GetType();
+
+    // Clean up variables in the current scope
+    for (int i = 0; i < func_symtbl->GetNumVariables(); i++) {
+      switch (func_symtbl->GetVariableType(i).type) {
+        case TYPE(ARRAY):       m_call_stack[sp + i].as_array->RemoveReference(); break;
+        case TYPE(BOOL):        break;
+        case TYPE(CHAR):        break;
+        case TYPE(INT):         break;
+        case TYPE(FLOAT):       break;
+        case TYPE(MATRIX):      break; // @TODO - cleanup scope
+        case TYPE(OBJECT_REF):  delete m_call_stack[sp + i].as_ref; break;
+        case TYPE(STRING):      delete m_call_stack[sp + i].as_string; break;
+        default: break;
+      }
+    }
+    
+    // Restore previous scope
+    m_has_returned = false;
+    m_call_stack.Resize(m_call_stack.GetSize() - m_cur_symtbl->GetNumVariables());
+    m_sp -= prev_symtbl->GetNumVariables();
+    m_cur_symtbl = prev_symtbl;
   }
-  
-  // Restore previous scope
-  m_has_returned = false;
-  m_call_stack.Resize(m_call_stack.GetSize() - m_cur_symtbl->GetNumVariables());
-  m_sp -= prev_symtbl->GetNumVariables();
-  m_cur_symtbl = prev_symtbl;
 }
 
 

Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc	2008-03-17 04:08:02 UTC (rev 2458)
+++ development/source/script/cSemanticASTVisitor.cc	2008-03-17 19:57:20 UTC (rev 2459)
@@ -214,6 +214,11 @@
 
 void cSemanticASTVisitor::VisitFunctionDefinition(cASTFunctionDefinition& node)
 {
+  if (m_library->HasFunction(node.GetName())) {
+    SEMANTIC_ERROR(CANNOT_OVERRIDE_LIB_FUNCTION, (const char*)node.GetName());
+    return;
+  }
+  
   int fun_id = -1;
   bool added = m_cur_symtbl->AddFunction(node.GetName(), node.GetType(), fun_id);
   
@@ -626,9 +631,42 @@
     return;
   }
   
+  const cASFunction* libfun = NULL;
   int fun_id = -1;
   bool global = false;
-  if (lookupFunction(node.GetName(), fun_id, global)) {
+
+  if (m_library->LookupFunction(node.GetName(), libfun)) {
+    // Check function parameters for match to the signature
+    cASTArgumentList* args = node.GetArguments();
+    if (args && libfun->GetArity() == args->GetSize()) { 
+      bool err = false;
+      tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
+      cASTNode* an = NULL;
+      for (int i = 0; i < libfun->GetArity(); i++) {
+        an = cit.Next();
+        an->Accept(*this);
+        
+        ASType_t in_type = an->GetType().type;
+        ASType_t out_type = libfun->GetArgumentType(i).type;
+        if (valid_cast[in_type][out_type]) {
+          if ((in_type == TYPE(FLOAT) && out_type == TYPE(INT)) || (in_type == TYPE(INT) && out_type == TYPE(CHAR))) 
+            SEMANTIC_WARNING(LOSS_OF_PRECISION, mapType(in_type), mapType(out_type)); 
+        } else { 
+          if (!err) {
+            SEMANTIC_ERROR(FUNCTION_CALL_SIGNATURE_MISMATCH, (const char*)node.GetName());
+            err = true;
+          }
+          SEMANTIC_ERROR(CANNOT_CAST, mapType(in_type), mapType(out_type)); 
+        }
+      }
+    } else if (libfun->GetArity()) {
+      SEMANTIC_ERROR(FUNCTION_CALL_SIGNATURE_MISMATCH, (const char*)node.GetName());
+    }
+    
+    node.SetASFunction(libfun);
+    node.SetType(libfun->GetReturnType());
+    
+  } else if (lookupFunction(node.GetName(), fun_id, global)) {
     cASTVariableDefinitionList* sig = (global ? m_global_symtbl : m_cur_symtbl)->GetFunctionSignature(fun_id);
     
     // Check function parameters for match to the signature
@@ -961,6 +999,9 @@
     case AS_SEMANTIC_ERR_CANNOT_COMPARE:
       std::cerr << "cannot compare values" << ERR_ENDL; 
       break;
+    case AS_SEMANTIC_ERR_CANNOT_OVERRIDE_LIB_FUNCTION:
+      std::cerr << "cannot override library method '" << VA_ARG_STR << "()'" << ERR_ENDL;
+      break;
     case AS_SEMANTIC_ERR_FUNCTION_CALL_SIGNATURE_MISMATCH:
       std::cerr << "invalid call signature for '" << VA_ARG_STR << "()'" << ERR_ENDL;
       break;




More information about the Avida-cvs mailing list